home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / small_c.arc / CC.ARC < prev    next >
Text File  |  1985-09-14  |  79KB  |  3,147 lines

  1. >>> STDIO.H 387
  2. /*
  3. ** STDIO.H -- Standard Small-C Definitions
  4. **
  5. ** Copyright 1983  L. E. Payne and J. E. Hendrix
  6. */
  7. #define stdin    0
  8. #define stdout   1
  9. #define stderr   2
  10. #define stdaux   3
  11. #define stdprn   4
  12. #define ERR   (-2)
  13. #define EOF   (-1)
  14. #define YES      1
  15. #define NO       0
  16. #define NULL     0
  17. #define CR      13
  18. #define LF      10
  19. #define BELL     7
  20. #define SPACE  ' '
  21. #define NEWLINE LF
  22.  
  23. >>> NOTICE.H 124
  24. #define VERSION "Small-C Compiler, Version 2.1, (Rev. 70)\n"
  25. #define CRIGHT1 "Copyright 1982, 1983, 1985 J. E. Hendrix\n\n"
  26. >>> CC.DEF 5310
  27. /*
  28. ** CC.DEF -- Symbol Definitions for Small-C compiler.
  29. */
  30.  
  31. /*
  32. ** compile options
  33. */
  34. #define NOCCARGC /* no argument counts */
  35. #define SEPARATE /* compile separately */
  36. #define OPTIMIZE /* compile output optimizer */
  37. #define DYNAMIC  /* allocate memory dynamically */
  38. #define COL      /* terminate labels with a colon */
  39. /* #define UPPER    /* force symbols to upper case */
  40. #define LINK     /* will use with linking loader */
  41.  
  42. /*
  43. ** machine dependent parameters
  44. */
  45. #define BPW     2   /* bytes per word */
  46. #define LBPW    1   /* log2(BPW) */
  47. #define SBPC    1   /* stack bytes per character */
  48. #define ERRCODE 7   /* op sys return code */
  49.  
  50. /*
  51. ** symbol table format
  52. */
  53. #define IDENT    0
  54. #define TYPE     1
  55. #define CLASS    2
  56. #define OFFSET   3
  57. #define NAME     5
  58. #define OFFSIZE (NAME-OFFSET)
  59. #define SYMAVG  10
  60. #define SYMMAX  14
  61.  
  62. /*
  63. ** symbol table parameters
  64. */
  65. #define NUMLOCS   25
  66. #define STARTLOC  symtab
  67. #define ENDLOC    (symtab+NUMLOCS*SYMAVG)
  68. #define NUMGLBS   200
  69. #define STARTGLB  ENDLOC
  70. #define ENDGLB    (ENDLOC+(NUMGLBS-1)*SYMMAX)
  71. #define SYMTBSZ   3050  /* (NUMLOCS*SYMAVG + NUMGLBS*SYMMAX) */
  72.  
  73. /*
  74. ** System wide name size (for symbols)
  75. */
  76. #define NAMESIZE 9
  77. #define NAMEMAX  8
  78.  
  79. /*
  80. ** possible entries for "IDENT"
  81. */
  82. #define LABEL    0
  83. #define VARIABLE 1
  84. #define ARRAY    2
  85. #define POINTER  3
  86. #define FUNCTION 4
  87.  
  88. /*
  89. ** possible entries for "TYPE"
  90. **    low order 2 bits make type unique within length
  91. **    high order bits give length of object
  92. */
  93. /*      LABEL   0 */
  94. #define CCHAR   (1<<2)
  95. #define CINT    (BPW<<2)
  96.  
  97. /*
  98. ** possible entries for "CLASS"
  99. */
  100. /*      LABEL     0 */
  101. #define STATIC    1
  102. #define AUTOMATIC 2
  103. #define EXTERNAL  3
  104. #define AUTOEXT   4
  105. #define GLOBAL    5
  106.  
  107. /*
  108. ** segment types
  109. */
  110. #define DATASEG 1
  111. #define CODESEG 2
  112.  
  113. /*
  114. ** "switch" table
  115. */
  116. #define SWSIZ   (2*BPW)
  117. #define SWTABSZ (90*SWSIZ)
  118.  
  119. /*
  120. ** "while" statement queue
  121. */
  122. #define WQTABSZ  30
  123. #define WQSIZ     3
  124. #define WQMAX   (wq+WQTABSZ-WQSIZ)
  125.  
  126. /*
  127. ** entry offsets in while queue
  128. */
  129. #define WQSP    0
  130. #define WQLOOP  1
  131. #define WQEXIT  2
  132.  
  133. /*
  134. ** literal pool
  135. */
  136. #define LITABSZ 1500
  137. #define LITMAX  (LITABSZ-1)
  138.  
  139. /*
  140. ** input line
  141. */
  142. #define LINEMAX  127
  143. #define LINESIZE 128
  144.  
  145. /*
  146. ** entries in staging buffer
  147. */
  148. #define STAGESIZE   200
  149.  
  150. /*
  151. ** macro (define) pool
  152. */
  153. #define MACNBR   300
  154. #define MACNSIZE (MACNBR*(NAMESIZE+2))
  155. #define MACNEND  (macn+MACNSIZE)
  156. #define MACQSIZE (MACNBR*7)
  157. #define MACMAX   (MACQSIZE-1)
  158.  
  159. /*
  160. ** statement types
  161. */
  162. #define STIF      1
  163. #define STWHILE   2
  164. #define STRETURN  3
  165. #define STBREAK   4
  166. #define STCONT    5
  167. #define STASM     6
  168. #define STEXPR    7
  169. #define STDO      8 /* compile "do" logic */
  170. #define STFOR     9 /* compile "for" logic */
  171. #define STSWITCH 10 /* compile "switch/case/default" logic */
  172. #define STCASE   11
  173. #define STDEF    12
  174. #define STGOTO   13 /* compile "goto" logic */
  175. #define STLABEL  14
  176.  
  177. /*
  178. ** compiler-generated p-codes
  179. */
  180. #define _LABEL    0
  181. #define _RLAB     1
  182. #define _GCHAR    2
  183. #define _GINT     3
  184. #define _LINT     4
  185. #define _LCHAR    5
  186. #define _GSTK     6
  187. #define _SCHAR    7
  188. #define _SINT     8
  189. #define _PINT     9
  190. #define _PCHAR    10
  191. #define _MOVE     11
  192. #define _SWAP     12
  193. #define _OFFSET   13
  194. #define _STRING   14
  195. #define _IMMED    15
  196. #define _IMMED2   16
  197. #define _PUSH     17
  198. #define _POP      18
  199. #define _SWAPSTK  19
  200. #define _SW       20
  201. #define _CALL     21
  202. #define _FUNC     22
  203. #define _RET      23
  204. #define _CALLSTK  24
  205. #define _JUMP     25
  206. #define _TESTJUMP 26
  207. #define _DEFBYTE  27
  208. #define _DEFWORD  28
  209. #define _DEFLABEL 29
  210. #define _MODSTK   30
  211. #define _DBL      31
  212. #define _DBL2     32
  213. #define _ADD      33
  214. #define _SUB      34
  215. #define _MULT     35
  216. #define _DIV      36
  217. #define _MOD      37
  218. #define _OR       38
  219. #define _XOR      39
  220. #define _AND      40
  221. #define _LNEG     41
  222. #define _ASR      42
  223. #define _ASL      43
  224. #define _NEG      44
  225. #define _COM      45
  226. #define _INC      46
  227. #define _DEC      47
  228. #define _EQ       48
  229. #define _EQ0      49
  230. #define _NE       50
  231. #define _NE0      51
  232. #define _LT       52
  233. #define _LT0      53
  234. #define _LE       54
  235. #define _LE0      55
  236. #define _GT       56
  237. #define _GT0      57
  238. #define _GE       58
  239. #define _GE0      59
  240. #define _ULT      60
  241. #define _ULT0     61
  242. #define _ULE      62
  243. #define _UGT      63
  244. #define _UGE      64
  245. #define _COUNT    65
  246. #define _DB       66
  247. #define _DBZERO   67
  248. #define _DW       68
  249. #define _DWZERO   69
  250.  
  251. /*
  252. ** optimizer-generated p-codes
  253. */
  254. #define _ANY      -1
  255. #define _FINT    100   /* fetch local int */
  256. #define _FCHAR   101   /* fetch local char */
  257. #define _GLIO    102   /* get local int with offset */
  258. #define _GLCO    103   /* get local char with offset */
  259. #define _GGIO1   104   /* get global int with offset */
  260. #define _GGIO2   105   /* continuation of _GGIO1 */
  261. #define _GGCO1   106   /* get global char with offset */
  262. #define _GGCO2   107   /* continuation OF _GGCO1 */
  263. #define _ADDI    108   /* add immediate */
  264. #define _SUBI    109   /* subtract immediate */
  265. #define _INT_I   110   /* indirect integer post incr */
  266. #define _INT_D   111   /* indirect integer post decr */
  267. #define _CHAR_I  112   /* indirect character post incr */
  268. #define _CHAR_D  113   /* indirect character post decr */
  269. #define _XXX_I1  114   /* direct int/char post incr */
  270. #define _XXX_D1  115   /* direct int/char post decr */
  271. #define _XXX_X2  116   /* continue _XXX_I1 and _XXX_D1 */
  272.  
  273. >>> CC1.C 3548
  274. /*
  275. ** Small-C Compiler Part 1
  276. */
  277. #include <stdio.h>
  278. #include "notice.h"
  279. #include "cc.def"
  280.  
  281. /*
  282. ** miscellaneous storage
  283. */
  284. int
  285. #ifdef STGOTO
  286.   nogo,     /* > 0 disables goto statements */
  287.   noloc,    /* > 0 disables block locals */
  288. #endif
  289.   op[16],   /* function addresses of binary operators */
  290.   op2[16],  /* same for unsigned operators */
  291.   opindex,  /* index to matched operator */
  292.   opsize,   /* size of operator in bytes */
  293.   swactive, /* true inside a switch */
  294.   swdefault,/* default label #, else 0 */
  295.  *swnext,   /* address of next entry */
  296.  *swend,    /* address of last table entry */
  297. #ifdef DYNAMIC
  298.  *stage,    /* output staging buffer */
  299.  *wq,       /* while queue */
  300. #else
  301.   stage[STAGESIZE*2],
  302.   wq[WQTABSZ],
  303. #endif
  304.   argcs,    /* static argc */
  305.  *argvs,    /* static argv */
  306.  *wqptr,    /* ptr to next entry */
  307.   litptr,   /* ptr to next entry */
  308.   macptr,   /* macro buffer index */
  309.   pptr,     /* ptr to parsing buffer */
  310.   oper,     /* address of binary operator function */
  311.   ch,       /* current character of line being scanned */
  312.   nch,      /* next character of line being scanned */
  313.   declared, /* # of local bytes declared, else -1 when done */
  314.   iflevel,  /* #if... nest level */
  315.   skiplevel,/* level at which #if... skipping started */
  316.   func1,    /* true for first function */
  317.   nxtlab,   /* next avail label # */
  318.   litlab,   /* label # assigned to literal pool */
  319.   beglab,   /* beginning label -- first function */
  320.   csp,      /* compiler relative stk ptr */
  321.   argstk,   /* function arg sp */
  322.   argtop,
  323.   ncmp,     /* # open compound statements */
  324.   errflag,  /* non-zero after 1st error in statement */
  325.   eof,      /* set non-zero on final input eof */
  326.   input,    /* fd # for input file */
  327.   input2,   /* fd # for "include" file */
  328.   output,   /* fd # for output file */
  329.   files,    /* non-zero if file list specified on cmd line */
  330.   filearg,  /* cur file arg index */
  331.   glbflag,  /* non-zero if internal globals */
  332.   ctext,    /* non-zero to intermix c-source */
  333.   ccode,    /* non-zero while parsing c-code */
  334.             /* zero when passing assembly code */
  335.  *stagenext,/* next addr in stage */
  336.  *stagetail,/* last addr of data in stage */
  337.  *stagelast,/* last addr in stage */
  338.   listfp,   /* file pointer to list device */
  339.   lastst,   /* last executed statement type */
  340.  *iptr,     /* work ptr to any int buffer */
  341.   oldseg;   /* current segment, 0, DATASEG, CODESEG */
  342.  
  343. char
  344. #ifdef OPTIMIZE
  345.   optimize, /* optimize output of staging buffer */
  346. #endif
  347.   alarm,    /* audible alarm on errors? */
  348.   monitor,  /* monitor function headers? */
  349.   pause,    /* pause for operator on errors? */
  350. #ifdef DYNAMIC
  351.  *symtab,   /* symbol table */
  352.  *litq,     /* literal pool */
  353.  *macn,     /* macro name buffer */
  354.  *macq,     /* macro string buffer */
  355.  *pline,    /* parsing buffer */
  356.  *mline,    /* macro buffer */
  357. #else
  358.   symtab[SYMTBSZ],
  359.   litq[LITABSZ],
  360.   macn[MACNSIZE],
  361.   macq[MACQSIZE],
  362.   pline[LINESIZE],
  363.   mline[LINESIZE],
  364.   swq[SWTABSZ],
  365. #endif
  366.  *line,     /* points to pline or mline */
  367.  *lptr,     /* ptr to either */
  368.  *glbptr,   /* ptrs to next entries */
  369.  *locptr,   /* ptr to next local symbol */
  370.   quote[2], /* literal string for '"' */
  371.  *cptr,     /* work ptrs to any char buffer */
  372.  *cptr2,
  373.  *cptr3,
  374.   msname[NAMESIZE], /* macro symbol name array */
  375.   ssname[NAMESIZE]; /* static symbol name array */
  376.  
  377. #include "cc11.c"
  378. #include "cc12.c"
  379. #include "cc13.c"
  380.  
  381. #ifndef SEPARATE
  382. #include "cc21.c"
  383. #include "cc22.c"
  384. #include "cc31.c"
  385. #include "cc32.c"
  386. #include "cc33.c"
  387. #include "cc41.c"
  388. #include "cc42.c"
  389. #endif
  390.  
  391. >>> CC11.C 5513
  392. /*
  393. ** execution begins here
  394. */
  395. main(argc, argv) int argc, *argv; {
  396.   fputs(VERSION, stderr);
  397.   fputs(CRIGHT1, stderr);
  398.   argcs=argc;
  399.   argvs=argv;
  400. #ifdef DYNAMIC
  401.   swnext=calloc(SWTABSZ, 1);
  402.   swend=swnext+((SWTABSZ-SWSIZ)>>1);
  403.   stage=calloc(STAGESIZE, 2*BPW);
  404.   wq=calloc(WQTABSZ, BPW);
  405.   litq=calloc(LITABSZ, 1);
  406.   macn=calloc(MACNSIZE, 1);
  407.   macq=calloc(MACQSIZE, 1);
  408.   pline=calloc(LINESIZE, 1);
  409.   mline=calloc(LINESIZE, 1);
  410. #else
  411.   swend=(swnext=swq)+SWTABSZ-SWSIZ;
  412. #endif
  413.   stagelast=stage+(STAGESIZE*2*BPW);
  414.   swactive=       /* not in switch */
  415.   stagenext=      /* direct-output mode */
  416.   iflevel=        /* #if... nesting level = 0 */
  417.   skiplevel=      /* #if... not encountered */
  418.   macptr=         /* clear the macro pool */
  419.   csp =           /* stack ptr (relative) */
  420.   errflag=        /* not skipping errors till ";" */
  421.   eof=            /* not eof yet */
  422.   ncmp=           /* not in compound statement */
  423.   files=
  424.   filearg=
  425.   quote[1]=0;
  426.   func1=          /* first function */
  427.   ccode=1;        /* enable preprocessing */
  428.   wqptr=wq;       /* clear while queue */
  429.   quote[0]='"';   /* fake a quote literal */
  430.   input=input2=EOF;
  431.   ask();          /* get user options */
  432.   openfile();     /* and initial input file */
  433.   preprocess();   /* fetch first line */
  434. #ifdef DYNAMIC
  435.   symtab=calloc((NUMLOCS*SYMAVG + NUMGLBS*SYMMAX), 1);
  436. #endif
  437.   locptr=STARTLOC;
  438.   glbptr=STARTGLB;
  439.   glbflag=1;
  440.   ctext=0;
  441.   header();          /* intro code */
  442.   setops();          /* set values in op arrays */
  443.   parse();           /* process ALL input */
  444.   outside();         /* verify outside any function */
  445.   trailer();         /* follow-up code */
  446.   fclose(output);
  447.   }
  448.  
  449. /*
  450. ** process all input text
  451. **
  452. ** At this level, only static declarations,
  453. **      defines, includes and function
  454. **      definitions are legal...
  455. */
  456. parse() {
  457.   while (eof==0) {
  458.     if(amatch("extern", 6))      dodeclare(EXTERNAL);
  459.     else if(amatch("static", 6)) dodeclare(STATIC);
  460.     else if(dodeclare(GLOBAL))   ;
  461.     else if(match("#asm"))       doasm();
  462.     else if(match("#include"))   doinclude();
  463.     else if(match("#define"))    addmac();
  464.     else                         newfunc();
  465.     blanks();       /* force eof if pending */
  466.     }
  467.   }
  468.  
  469. /*
  470. ** dump the literal pool
  471. */
  472. dumplits(size) int size; {
  473.   int j, k; k=0;
  474.   while (k < litptr) {
  475.     poll(1);   /* allow program interruption */
  476.     if (size == 1) gen_code(_DB, NULL);
  477.     else           gen_code(_DW, NULL);
  478.     j = 10;
  479.     while(j--) {
  480.       outdec(getint(litq+k, size));
  481.       k += size;
  482.       if(j == 0 || k >= litptr) {nl(); break;}
  483.       outbyte(',');
  484.       }
  485.     }
  486.   }
  487.  
  488. /*
  489. ** dump zeroes for default initial values
  490. */
  491. dumpzero(size, count) int size, count; {
  492.   if(count > 0) {
  493.     if (size == 1) gen_code(_DBZERO, count);
  494.     else           gen_code(_DWZERO, count);
  495.     }
  496.   }
  497.  
  498. /*
  499. ** verify compile ends outside any function
  500. */
  501. outside()  {
  502.   if (ncmp) error("no closing bracket");
  503.   }
  504.  
  505. /*
  506. ** get run options
  507. */
  508. ask() {
  509.   int i;
  510.   i=listfp=nxtlab=0;
  511.   output=stdout;
  512. #ifdef OPTIMIZE
  513.   optimize=YES;
  514. #endif
  515.   alarm=monitor=pause=NO;
  516.   line=mline;
  517.   while(getarg(++i, line, LINESIZE, argcs, argvs)!=EOF) {
  518.     if(line[0]!='-') continue;
  519.     if((toupper(line[1])=='L')&(isdigit(line[2]))&(line[3]<=' ')) {
  520.       listfp=line[2]-'0';
  521.       continue;
  522.       }
  523. #ifdef OPTIMIZE
  524.     if(toupper(line[1])=='N' && toupper(line[2])=='O' && line[3]<=' ') {
  525.       optimize=NO;
  526.       continue;
  527.       }
  528. #endif
  529.     if(line[2]<=' ') {
  530.       if(toupper(line[1])=='A') {alarm=YES; continue;}
  531.       if(toupper(line[1])=='M') {monitor=YES; continue;}
  532.       if(toupper(line[1])=='P') {pause=YES; continue;}
  533.       }
  534. #ifndef LINK
  535.     if(toupper(line[1])=='B') {
  536.       bump(0); bump(2);
  537.       if(number(&nxtlab)) continue;
  538.       }
  539. #endif
  540.     sout("usage: cc [file]... [-m] [-a] [-p] [-l#]", stderr);
  541. #ifdef OPTIMIZE
  542.     sout(" [-no]", stderr);
  543. #endif
  544. #ifndef LINK
  545.     sout(" [-b#]", stderr);
  546. #endif
  547.     sout("\n", stderr);
  548.     abort(ERRCODE);
  549.     }
  550.   }
  551.  
  552. /*
  553. ** input and output file opens
  554. */
  555. openfile() {        /* entire function revised */
  556.   char outfn[15];
  557.   int i, j, ext;
  558.   input=EOF;
  559.   while(getarg(++filearg, pline, LINESIZE, argcs, argvs)!=EOF) {
  560.     if(pline[0]=='-') continue;
  561.     ext = NO;
  562.     i = -1;
  563.     j = 0;
  564.     while(pline[++i]) {
  565.       if(pline[i] == '.') {
  566.         ext = YES;
  567.         break;
  568.         }
  569.       if(j < 10) outfn[j++] = pline[i];
  570.       }
  571.     if(!ext) {
  572.       strcpy(pline + i, ".C");
  573.       }
  574.     input = mustopen(pline, "r");
  575.     if(!files && isatty(stdout)) {
  576.       strcpy(outfn + j, ".ASM");
  577.       output = mustopen(outfn, "w");
  578.       }
  579.     files=YES;
  580.     kill();
  581.     return;
  582.     }
  583.   if(files++) eof=YES;
  584.   else input=stdin;
  585.   kill();
  586.   }
  587.  
  588. /*
  589. ** open a file with error checking
  590. */
  591. mustopen(fn, mode) char *fn, *mode; {
  592.   int fd;
  593.   if(fd = fopen(fn, mode)) return fd;
  594.   sout("open error on ", stderr);
  595.   lout(fn, stderr);
  596.   abort(ERRCODE);
  597.   }
  598.  
  599. setops() {
  600.   op2[ 0]=       op[ 0]=  _OR;  /* heir5 */
  601.   op2[ 1]=       op[ 1]= _XOR;  /* heir6 */
  602.   op2[ 2]=       op[ 2]= _AND;  /* heir7 */
  603.   op2[ 3]=       op[ 3]=  _EQ;  /* heir8 */
  604.   op2[ 4]=       op[ 4]=  _NE;
  605.   op2[ 5]=_ULE;  op[ 5]=  _LE;  /* heir9 */
  606.   op2[ 6]=_UGE;  op[ 6]=  _GE;
  607.   op2[ 7]=_ULT;  op[ 7]=  _LT;
  608.   op2[ 8]=_UGT;  op[ 8]=  _GT;
  609.   op2[ 9]=       op[ 9]= _ASR;  /* heir10 */
  610.   op2[10]=       op[10]= _ASL;
  611.   op2[11]=       op[11]= _ADD;  /* heir11 */
  612.   op2[12]=       op[12]= _SUB;
  613.   op2[13]=       op[13]=_MULT;  /* heir12 */
  614.   op2[14]=       op[14]= _DIV;
  615.   op2[15]=       op[15]= _MOD;
  616.   }
  617.  
  618. >>> CC12.C 7088
  619. /*
  620. ** open an include file
  621. */
  622. doinclude() {
  623.   int i; char str[30];
  624.   blanks();       /* skip over to name */
  625.   if(*lptr == '"' || *lptr == '<') ++lptr;
  626.   i=0;
  627.   while(lptr[i] && lptr[i] != '"' && lptr[i] != '>' && lptr[i] != '\n') {
  628.     str[i] = lptr[i];
  629.     ++i;
  630.     }
  631.   str[i] = NULL;
  632.   if((input2=fopen(str,"r")) == NULL) {
  633.     input2 = EOF;
  634.     error("open failure on include file");
  635.     }
  636.   kill();   /* make next read come from new file (if open) */
  637.   }
  638.  
  639. /*
  640. ** test for global declarations
  641. */
  642. dodeclare(class) int class; {
  643.   if(amatch("char",4)) {
  644.     declglb(CCHAR, class);
  645.     ns();
  646.     return 1;
  647.     }
  648.   else if((amatch("int",3))|(class==EXTERNAL)|(class==STATIC)) {
  649.     declglb(CINT, class);
  650.     ns();
  651.     return 1;
  652.     }
  653.   return 0;
  654.   }
  655.  
  656. /*
  657. ** declare a static variable
  658. */
  659. declglb(type, class)  int type, class; {
  660.   int k, j;
  661.   while(1) {
  662.     if(endst()) return;     /* do line */
  663.     if(match("(*")|match("*")) {
  664.       j=POINTER;
  665.       k=0;
  666.       }
  667.     else {
  668.       j=VARIABLE;
  669.       k=1;
  670.       }
  671.     if (symname(ssname, YES)==0) illname();
  672.     if(findglb(ssname)) multidef(ssname);
  673.     if(match(")")) ;
  674.     if(match("()")) j=FUNCTION;
  675.     else if (match("[")) {
  676.       paerror(j);
  677.       k=needsub();    /* get size */
  678.       j=ARRAY;   /* !0=array */
  679.       }
  680.     if(class==EXTERNAL) external(ssname, type>>2, j);
  681.     else if(j!=FUNCTION) j=initials(type>>2, j, k);
  682.     addsym(ssname, j, type, k, &glbptr, class);
  683.     if (match(",")==0) return; /* more? */
  684.     }
  685.   }
  686.  
  687. /*
  688. ** declare local variables
  689. */
  690. declloc(typ)  int typ;  {
  691.   int k,j;
  692.   if(swactive) error("not allowed in switch");
  693. #ifdef STGOTO
  694.   if(noloc) error("not allowed with goto");
  695. #endif
  696.   if(declared < 0) error("must declare first in block");
  697.   while(1) {
  698.     while(1) {
  699.       if(endst()) return;
  700.       if(match("(*") | match("*")) j=POINTER;
  701.       else           j=VARIABLE;
  702.       if (symname(ssname, YES)==0) illname();
  703.       if(match(")")) ;
  704.       if(match("()")) j=FUNCTION;
  705.       /* no multidef check, block-locals are together */
  706.       k=BPW;
  707.       if (match("[")) {
  708.         paerror(j);
  709.         if(k=needsub()) {
  710.           j=ARRAY;
  711.           if(typ==CINT)k=k<<LBPW;
  712.           }
  713.         else {j=POINTER; k=BPW;}
  714.         }
  715.       else if((typ==CCHAR)&(j==VARIABLE)) k=SBPC;
  716.       declared = declared + k;
  717.       addsym(ssname, j, typ, csp - declared, &locptr, AUTOMATIC);
  718.       break;
  719.       }
  720.     if (match(",")==0) return;
  721.     }
  722.   }
  723.  
  724. /*
  725. ** test for pointer array (unsupported)
  726. */
  727. paerror(j) int j; {
  728.   if(j==POINTER) error("no pointer arrays");
  729.   }
  730.  
  731. /*
  732. ** initialize global objects
  733. */
  734. initials(size, ident, dim) int size, ident, dim; {
  735.   int savedim;
  736.   litptr=0;
  737.   if(dim==0) dim = -1;
  738.   savedim=dim;
  739.   public(size, ident);
  740.   if(match("=")) {
  741.     if(match("{")) {
  742.       while(dim) {
  743.         init(size, ident, &dim);
  744.         if(match(",")==0) break;
  745.         }
  746.       needtoken("}");
  747.       }
  748.     else init(size, ident, &dim);
  749.     }
  750.   if((dim == -1)&(dim==savedim)) {
  751.     stowlit(0, size=BPW);
  752.     ident=POINTER;
  753.     }
  754.   dumplits(size);
  755.   dumpzero(size, dim);
  756.   return ident;
  757.   }
  758.  
  759. /*
  760. ** evaluate one initializer
  761. */
  762. init(size, ident, dim) int size, ident, *dim; {
  763.   int value;
  764.   if(qstr(&value)) {
  765.     if((ident==VARIABLE)|(size!=1))
  766.       error("must assign to char pointer or array");
  767.     *dim = *dim - (litptr - value);
  768.     if(ident==POINTER) point();
  769.     }
  770.   else if(constexpr(&value)) {
  771.     if(ident==POINTER) error("cannot assign to pointer");
  772.     stowlit(value, size);
  773.     *dim = *dim - 1;
  774.     }
  775.   }
  776.  
  777. /*
  778. ** get required array size
  779. */
  780. needsub()  {
  781.   int val;
  782.   if(match("]")) return 0; /* null size */
  783.   if (constexpr(&val)==0) val=1;
  784.   if (val<0) {
  785.     error("negative size illegal");
  786.     val = -val;
  787.     }
  788.   needtoken("]");      /* force single dimension */
  789.   return val;          /* and return size */
  790.   }
  791.  
  792. /*
  793. ** begin a function
  794. **
  795. ** called from "parse" and tries to make a function
  796. ** out of the following text
  797. */
  798. newfunc()  {
  799.   char *ptr;
  800. #ifdef STGOTO
  801.   nogo  =             /* enable goto statements */
  802.   noloc = 0;          /* enable block-local declarations */
  803. #endif
  804.   lastst=             /* no statement yet */
  805.   litptr=0;           /* clear lit pool */
  806.   litlab=getlabel();  /* label next lit pool */
  807.   locptr=STARTLOC;    /* clear local variables */
  808.   if(monitor) lout(line, stderr);
  809.   if (symname(ssname, YES)==0) {
  810.     error("illegal function or declaration");
  811.     kill(); /* invalidate line */
  812.     return;
  813.     }
  814.   if(ptr=findglb(ssname)) {      /* already in symbol table ? */
  815.     if(ptr[IDENT]!=FUNCTION)       multidef(ssname);
  816.     else if(ptr[OFFSET]==FUNCTION) multidef(ssname);
  817.     else {
  818.       /*  earlier assumed to be a function */
  819.       ptr[OFFSET]=FUNCTION;
  820.       ptr[CLASS]=GLOBAL;
  821.       }
  822.     }
  823.   else
  824.     addsym(ssname, FUNCTION, CINT, FUNCTION, &glbptr, GLOBAL);
  825.   if(match("(")==0) error("no open paren");
  826.   public(CINT>>2, FUNCTION);
  827.   locptr=STARTLOC;
  828.   argstk=0;               /* init arg count */
  829.   while(match(")")==0) {  /* then count args */
  830.     /* any legal name bumps arg count */
  831.     if(symname(ssname, YES)) {
  832.       if(findloc(ssname)) multidef(ssname);
  833.       else {
  834.         addsym(ssname, 0, 0, argstk, &locptr, AUTOMATIC);
  835.         argstk=argstk+BPW;
  836.         }
  837.       }
  838.     else {error("illegal argument name");junk();}
  839.     blanks();
  840.     /* if not closing paren, should be comma */
  841.     if(streq(lptr,")")==0) {
  842.       if(match(",")==0) error("no comma");
  843.       }
  844.     if(endst()) break;
  845.     }
  846.   csp=0;        /* preset stack ptr */
  847.   argtop=argstk+BPW; /* account for the pushed BP */
  848.   while(argstk) {
  849.     /* now let user declare what types of things */
  850.     /*      those arguments were */
  851.     if(amatch("char",4))     {doargs(CCHAR);ns();}
  852.     else if(amatch("int",3)) {doargs(CINT);ns();}
  853.     else {error("wrong number of arguments");break;}
  854.     }
  855.   gen_code(_FUNC, 0);
  856.   statement();
  857. #ifdef STGOTO
  858.   if(lastst != STRETURN && lastst != STGOTO) gen_code(_RET, 0);
  859. #else
  860.   if(lastst != STRETURN) gen_code(_RET, 0);
  861. #endif
  862.   if(litptr) {
  863.     toseg(DATASEG);
  864.     gen_code(_RLAB, litlab);
  865.     dumplits(1); /* dump literals */
  866.     }
  867.   }
  868.  
  869. /*
  870. ** declare argument types
  871. **
  872. ** called from "newfunc" this routine adds an entry in the
  873. ** local symbol table for each named argument.  The arguments are
  874. ** of type 't'.
  875. */
  876. doargs(t) int t; {
  877.   int j, legalname;
  878.   char c, *argptr;
  879.   while(1) {
  880.     if(argstk==0) return; /* no arguments */
  881.     if(match("(*")|match("*")) j=POINTER;  else j=VARIABLE;
  882.     if((legalname=symname(ssname, YES))==0) illname();
  883.     if(match(")")) ;
  884.     if(match("()")) ;
  885.     if(match("[")) {   /* is it a pointer? */
  886.       paerror(j);
  887.       while(inbyte()!=']') if(endst()) break; /*skip "[...]" */
  888.       j=POINTER; /* add entry as pointer */
  889.       }
  890.     if(legalname) {
  891.       if(argptr=findloc(ssname)) {
  892.         /* add details of type and address */
  893.         argptr[IDENT]=j;
  894.         argptr[TYPE]=t;
  895.         putint(argtop-getint(argptr+OFFSET, OFFSIZE), argptr+OFFSET, OFFSIZE);
  896.         }
  897.       else error("not an argument");
  898.       }
  899.     argstk=argstk-BPW;        /* cnt down */
  900.     if(endst())return;
  901.     if(match(",")==0) error("no comma");
  902.     }
  903.   }
  904.  
  905. >>> CC13.C 7407
  906. /*
  907. ** statement parser
  908. **
  909. ** called whenever syntax requires a statement
  910. **  this routine performs that statement
  911. **  and returns a number telling which one
  912. */
  913. statement() {
  914.   if ((ch==0) & (eof)) return;
  915.   else if(amatch("static",6)){declglb(STATIC);ns();}
  916.   else if(amatch("char",4))  {declloc(CCHAR);ns();}
  917.   else if(amatch("int",3))   {declloc(CINT);ns();}
  918.   else {
  919.     if(declared >= 0) {
  920. #ifdef STGOTO
  921.       if(ncmp > 1) nogo=declared; /* disable goto if any */
  922. #endif
  923.       gen_code(_MODSTK, csp - declared);
  924.       declared = -1;
  925.       }
  926.     if(match("{"))               compound();
  927.     else if(amatch("if",2))      {doif();          lastst=STIF;}
  928.     else if(amatch("while",5))   {dowhile();       lastst=STWHILE;}
  929. #ifdef STDO
  930.     else if(amatch("do",2))      {dodo();          lastst=STDO;}
  931. #endif
  932. #ifdef STFOR
  933.     else if(amatch("for",3))     {dofor();         lastst=STFOR;}
  934. #endif
  935. #ifdef STSWITCH
  936.     else if(amatch("switch",6))  {doswitch();      lastst=STSWITCH;}
  937.     else if(amatch("case",4))    {docase();        lastst=STCASE;}
  938.     else if(amatch("default",7)) {dodefault();     lastst=STDEF;}
  939. #endif
  940. #ifdef STGOTO
  941.     else if(amatch("goto", 4))   {dogoto();        lastst=STGOTO;}
  942.     else if(dolabel())                             lastst=STLABEL;
  943. #endif
  944.     else if(amatch("return",6))  {doreturn();ns(); lastst=STRETURN;}
  945.     else if(amatch("break",5))   {dobreak();ns();  lastst=STBREAK;}
  946.     else if(amatch("continue",8)){docont();ns();   lastst=STCONT;}
  947.     else if(match(";"))          errflag=0;
  948.     else if(match("#asm"))       {doasm();         lastst=STASM;}
  949.     else                         {doexpr();ns();   lastst=STEXPR;}
  950.     }
  951.   return lastst;
  952.   }
  953.  
  954. /*
  955. ** semicolon enforcer
  956. **
  957. ** called whenever syntax requires a semicolon
  958. */
  959. ns()  {
  960.   if(match(";")==0) error("no semicolon");
  961.   else errflag=0;
  962.   }
  963.  
  964. compound()  {
  965.   int savcsp;
  966.   char *savloc;
  967.   savcsp=csp;
  968.   savloc=locptr;
  969.   declared=0;    /* may now declare local variables */
  970.   ++ncmp;        /* new level open */
  971.   while (match("}")==0)
  972.     if(eof) {
  973.       error("no final }");
  974.       break;
  975.       }
  976.     else statement();     /* do one */
  977.   --ncmp;                 /* close current level */
  978. #ifdef STGOTO
  979.   if(lastst != STRETURN && lastst != STGOTO)
  980. #else
  981.   if(lastst != STRETURN)
  982. #endif
  983.     gen_code(_MODSTK, savcsp); /* delete local variable space */
  984.   csp = savcsp;
  985. #ifdef STGOTO
  986.   cptr=savloc;            /* retain labels */
  987.   while(cptr < locptr) {
  988.     cptr2=nextsym(cptr);
  989.     if(cptr[IDENT] == LABEL) {
  990.       while(cptr < cptr2) *savloc++ = *cptr++;
  991.       }
  992.     else cptr=cptr2;
  993.     }
  994. #endif
  995.   locptr=savloc;          /* delete local symbols */
  996.   declared = -1;          /* may not declare variables */
  997.   }
  998.  
  999. doif()  {
  1000.   int flab1,flab2;
  1001.   flab1=getlabel(); /* get label for false branch */
  1002.   test(flab1, YES); /* get expression, and branch false */
  1003.   statement();      /* if true, do a statement */
  1004.   if (amatch("else",4)==0) {      /* if...else ? */
  1005.     /* simple "if"...print false label */
  1006.     gen_code(_LABEL, flab1);
  1007.     return;         /* and exit */
  1008.     }
  1009.   flab2=getlabel();
  1010. #ifdef STGOTO
  1011.   if((lastst != STRETURN)&(lastst != STGOTO)) gen_code(_JUMP, flab2);
  1012. #else
  1013.   if(lastst != STRETURN) gen_code(_JUMP, flab2);
  1014. #endif
  1015.   gen_code(_LABEL, flab1); /* print false label */
  1016.   statement();      /* and do "else" clause */
  1017.   gen_code(_LABEL, flab2); /* print true label */
  1018.   }
  1019.  
  1020. doexpr() {
  1021.   int const, val;
  1022.   int *before, *start;
  1023.   while(1) {
  1024.     setstage(&before, &start);
  1025.     expression(&const, &val);
  1026.     clearstage(before, start);
  1027.     if(ch != ',') break;
  1028.     bump(1);
  1029.     }
  1030.   }
  1031.  
  1032. dowhile()  {
  1033.   int wq[4];              /* allocate local queue */
  1034.   addwhile(wq);           /* add entry to queue for "break" */
  1035.   gen_code(_LABEL, wq[WQLOOP]);  /* loop label */
  1036.   test(wq[WQEXIT], YES);  /* see if true */
  1037.   statement();            /* if so, do a statement */
  1038.   gen_code(_JUMP, wq[WQLOOP]);       /* loop to label */
  1039.   gen_code(_LABEL, wq[WQEXIT]);  /* exit label */
  1040.   delwhile();             /* delete queue entry */
  1041.   }
  1042.  
  1043. #ifdef STDO
  1044. dodo() {
  1045.   int wq[4], top;
  1046.   addwhile(wq);
  1047.   gen_code(_LABEL, top=getlabel());
  1048.   statement();
  1049.   needtoken("while");
  1050.   gen_code(_LABEL, wq[WQLOOP]);
  1051.   test(wq[WQEXIT], YES);
  1052.   gen_code(_JUMP, top);
  1053.   gen_code(_LABEL, wq[WQEXIT]);
  1054.   delwhile();
  1055.   ns();
  1056.   }
  1057. #endif
  1058.  
  1059. #ifdef STFOR
  1060. dofor() {
  1061.   int wq[4], lab1, lab2;
  1062.   addwhile(wq);
  1063.   lab1=getlabel();
  1064.   lab2=getlabel();
  1065.   needtoken("(");
  1066.   if(match(";")==0) {
  1067.     doexpr();            /* expr 1 */
  1068.     ns();
  1069.     }
  1070.   gen_code(_LABEL, lab1);
  1071.   if(match(";")==0) {
  1072.     test(wq[WQEXIT], NO); /* expr 2 */
  1073.     ns();
  1074.     }
  1075.   gen_code(_JUMP, lab2);
  1076.   gen_code(_LABEL, wq[WQLOOP]);
  1077.   if(match(")")==0) {
  1078.     doexpr();            /* expr 3 */
  1079.     needtoken(")");
  1080.     }
  1081.   gen_code(_JUMP, lab1);
  1082.   gen_code(_LABEL, lab2);
  1083.   statement();
  1084.   gen_code(_JUMP, wq[WQLOOP]);
  1085.   gen_code(_LABEL, wq[WQEXIT]);
  1086.   delwhile();
  1087.   }
  1088. #endif
  1089.  
  1090. #ifdef STSWITCH
  1091. doswitch() {
  1092.   int wq[4], endlab, swact, swdef, *swnex, *swptr;
  1093.   swact=swactive;
  1094.   swdef=swdefault;
  1095.   swnex=swptr=swnext;
  1096.   addwhile(wq);
  1097.   *(wqptr + WQLOOP - WQSIZ) = 0;
  1098.   needtoken("(");
  1099.   doexpr();                            /* evaluate switch expression */
  1100.   needtoken(")");
  1101.   swdefault=0;
  1102.   swactive=1;
  1103.   gen_code(_JUMP, endlab=getlabel());
  1104.   statement();   /* cases, etc. */
  1105.   gen_code(_JUMP, wq[WQEXIT]);
  1106.   gen_code(_LABEL, endlab);
  1107.   gen_code(_SW, 0);                    /* match cases */
  1108.   while(swptr < swnext) {
  1109.     gen_code(_DEFLABEL, *swptr++);
  1110.     gen_code(_DEFWORD, *swptr++);      /* case value */
  1111.     }
  1112.   gen_code(_DEFWORD, 0);
  1113.   if(swdefault) gen_code(_JUMP, swdefault);
  1114.   gen_code(_LABEL, wq[WQEXIT]);
  1115.   delwhile();
  1116.   swnext=swnex;
  1117.   swdefault=swdef;
  1118.   swactive=swact;
  1119.   }
  1120.  
  1121. docase() {
  1122.   if(swactive==0) error("not in switch");
  1123.   if(swnext > swend) {
  1124.     error("too many cases");
  1125.     return;
  1126.     }
  1127.   gen_code(_LABEL, *swnext++ = getlabel());
  1128.   constexpr(swnext++);
  1129.   needtoken(":");
  1130.   }
  1131.  
  1132. dodefault() {
  1133.   if(swactive) {
  1134.     if(swdefault) error("multiple defaults");
  1135.     }
  1136.   else error("not in switch");
  1137.   needtoken(":");
  1138.   gen_code(_LABEL, swdefault=getlabel());
  1139.   }
  1140. #endif
  1141.  
  1142. #ifdef STGOTO
  1143. dogoto() {
  1144.   if(nogo > 0) error("not allowed with block-locals");
  1145.   else noloc = 1;
  1146.   if(symname(ssname, YES)) gen_code(_JUMP, addlabel());
  1147.   else error("bad label");
  1148.   ns();
  1149.   }
  1150.  
  1151. dolabel() {
  1152.   char *savelptr;
  1153.   blanks();
  1154.   savelptr=lptr;
  1155.   if(symname(ssname, YES)) {
  1156.     if(gch()==':') {
  1157.       gen_code(_LABEL, addlabel());
  1158.       return 1;
  1159.       }
  1160.     else bump(savelptr-lptr);
  1161.     }
  1162.   return 0;
  1163.   }
  1164.  
  1165. addlabel()  {
  1166.   if(cptr=findloc(ssname)) {
  1167.     if(cptr[IDENT]!=LABEL) error("not a label");
  1168.     }
  1169.   else cptr=addsym(ssname, LABEL, LABEL, getlabel(), &locptr, LABEL);
  1170.   return (getint(cptr+OFFSET, OFFSIZE));
  1171.   }
  1172. #endif
  1173.  
  1174. doreturn()  {
  1175.   int savcsp;
  1176.   if(endst()==0) doexpr();
  1177.   savcsp = csp;
  1178.   gen_code(_MODSTK, 0);
  1179.   gen_code(_RET, 0);
  1180.   csp = savcsp;
  1181.   }
  1182.  
  1183. dobreak()  {
  1184.   int *ptr;
  1185.   if ((ptr=readwhile(wqptr))==0) return;
  1186.   gen_code(_MODSTK, ptr[WQSP]);
  1187.   gen_code(_JUMP, ptr[WQEXIT]);
  1188.   }
  1189.  
  1190. docont()  {
  1191.   int *ptr;
  1192.   ptr = wqptr;
  1193.   while (1) {
  1194.     if ((ptr=readwhile(ptr))==0) return;
  1195.     if (ptr[WQLOOP]) break;
  1196.     }
  1197.   gen_code(_MODSTK, ptr[WQSP]);
  1198.   gen_code(_JUMP, ptr[WQLOOP]);
  1199.   }
  1200.  
  1201. doasm()  {
  1202.   ccode=0;                /* mark mode as "asm" */
  1203.   while (1) {
  1204.     inline();
  1205.     if (match("#endasm")) break;
  1206.     if(eof)break;
  1207.     sout(line, output);
  1208.     }
  1209.   kill();
  1210.   ccode=1;
  1211.   }
  1212.  
  1213. >>> CC2.C 650
  1214. /*
  1215. ** Small-C Compiler Part 2
  1216. */
  1217. #include <stdio.h>
  1218. #include "cc.def"
  1219.  
  1220. extern char
  1221. #ifdef DYNAMIC
  1222.  *symtab,
  1223.  *macn,
  1224.  *macq,
  1225.  *pline,
  1226.  *mline,
  1227. #else
  1228.   symtab[SYMTBSZ],
  1229.   macn[MACNSIZE],
  1230.   macq[MACQSIZE],
  1231.   pline[LINESIZE],
  1232.   mline[LINESIZE],
  1233. #endif
  1234. #ifdef OPTIMIZE
  1235.   optimize,
  1236. #endif
  1237.   alarm, *glbptr, *line, *lptr, *cptr, *cptr2,  *cptr3,
  1238.  *locptr, msname[NAMESIZE],  pause,  quote[2];
  1239.  
  1240. extern int
  1241. #ifdef DYNAMIC
  1242.   *wq,
  1243. #else
  1244.   wq[WQTABSZ],
  1245. #endif
  1246.   ccode,  ch,  csp,  eof,  errflag,  iflevel,
  1247.   input,  input2,  listfp,  macptr,  nch,
  1248.   nxtlab,  op[16],  opindex,  opsize,  output,  pptr,
  1249.   skiplevel,  *wqptr;
  1250.  
  1251. #include "cc21.c"
  1252. #include "cc22.c"
  1253.  
  1254. >>> CC21.C 4262
  1255. junk() {
  1256.   if(an(inbyte())) while(an(ch)) gch();
  1257.   else while(an(ch)==0) {
  1258.     if(ch==0) break;
  1259.     gch();
  1260.     }
  1261.   blanks();
  1262.   }
  1263.  
  1264. endst() {
  1265.   blanks();
  1266.   return ((streq(lptr,";")|(ch==0)));
  1267.   }
  1268.  
  1269. illname() {
  1270.   error("illegal symbol");
  1271.   junk();
  1272.   }
  1273.   
  1274.  
  1275. multidef(sname)  char *sname; {
  1276.   error("already defined");
  1277.   }
  1278.  
  1279. undef(sname)  char *sname; {
  1280.   error("undefined");
  1281.   }
  1282.  
  1283. needtoken(str)  char *str; {
  1284.   if (match(str)==0) error("missing token");
  1285.   }
  1286.  
  1287. needlval() {
  1288.   error("must be lvalue");
  1289.   }
  1290.  
  1291. findglb(sname)  char *sname; {
  1292.   if(search(sname, STARTGLB, SYMMAX, ENDGLB, NUMGLBS, NAME)) return cptr;
  1293.   return 0;
  1294.   }
  1295.  
  1296. findloc(sname)  char *sname;  {
  1297.   cptr = locptr - 1;  /* search backward for block locals */
  1298.   while(cptr > STARTLOC) {
  1299.     cptr = cptr - *cptr;
  1300.     if(astreq(sname, cptr, NAMEMAX)) return (cptr - NAME);
  1301.     cptr = cptr - NAME - 1;
  1302.     }
  1303.   return 0;
  1304.   }
  1305.  
  1306. addsym(sname, id, typ, value, lgptrptr, class)
  1307.   char *sname, id, typ;  int value, *lgptrptr, class; {
  1308.   if(lgptrptr == &glbptr) {
  1309.     if(cptr2=findglb(sname)) return cptr2;
  1310.     if(cptr==0) {
  1311.       error("global symbol table overflow");
  1312.       return 0;
  1313.       }
  1314.     }
  1315.   else {
  1316.     if(locptr > (ENDLOC-SYMMAX)) {
  1317.       error("local symbol table overflow");
  1318.       abort(ERRCODE);
  1319.       }
  1320.     cptr = *lgptrptr;
  1321.     }
  1322.   cptr[IDENT]=id;
  1323.   cptr[TYPE]=typ;
  1324.   cptr[CLASS]=class;
  1325.   putint(value, cptr+OFFSET, OFFSIZE);
  1326.   cptr3 = cptr2 = cptr + NAME;
  1327.   while(an(*sname)) *cptr2++ = *sname++;
  1328.   if(lgptrptr == &locptr) {
  1329.     *cptr2 = cptr2 - cptr3;         /* set length */
  1330.     *lgptrptr = ++cptr2;
  1331.     }
  1332.   return cptr;
  1333.   }
  1334.  
  1335. nextsym(entry) char *entry; {
  1336.   entry = entry + NAME;
  1337.   while(*entry++ >= ' '); /* find length byte */
  1338.   return entry;
  1339.   }
  1340.  
  1341. /*
  1342. ** get integer of length len from address addr
  1343. ** (byte sequence set by "putint")
  1344. */
  1345. getint(addr, len) char *addr; int len; {
  1346.   int i;
  1347.   i = *(addr + --len);  /* high order byte sign extended */
  1348.   while(len--) i = (i << 8) | *(addr+len)&255;
  1349.   return i;
  1350.   }
  1351.  
  1352. /*
  1353. ** put integer i of length len into address addr
  1354. ** (low byte first)
  1355. */
  1356. putint(i, addr, len) char *addr; int i, len; {
  1357.   while(len--) {
  1358.     *addr++ = i;
  1359.     i = i>>8;
  1360.     }
  1361.   }
  1362.  
  1363. /*
  1364. ** test if next input string is legal symbol name
  1365. */
  1366. symname(sname, ucase) char *sname; int ucase; {
  1367.   int k;char c;
  1368.   blanks();
  1369.   if(alpha(ch)==0) return (*sname=0);   /*19*/
  1370.   k=0;
  1371.   while(an(ch)) {
  1372. #ifdef UPPER
  1373.     if(ucase)
  1374.       sname[k]=toupper(gch());
  1375.     else
  1376. #endif
  1377.       sname[k]=gch();
  1378.     if(k<NAMEMAX) ++k;
  1379.     }
  1380.   sname[k]=0;
  1381.   return 1;
  1382.   }
  1383.  
  1384. /*
  1385. ** return next avail internal label number
  1386. */
  1387. getlabel() {
  1388.   return(++nxtlab);
  1389.   }
  1390.  
  1391. /*
  1392. ** test if c is alphabetic
  1393. */
  1394. alpha(c)  char c; {
  1395.   return (isalpha(c) | c=='_');
  1396.   }
  1397.  
  1398. /*
  1399. ** test if given character is alphanumeric
  1400. */
  1401. an(c)  char c; {
  1402.   return (alpha(c) | isdigit(c));
  1403.   }
  1404.  
  1405. addwhile(ptr)  int ptr[]; {
  1406.   int k;
  1407.   ptr[WQSP]=csp;           /* and stk ptr */
  1408.   ptr[WQLOOP]=getlabel();  /* and looping label */
  1409.   ptr[WQEXIT]=getlabel();   /* and exit label */
  1410.   if (wqptr==WQMAX) {
  1411.     error("too many active loops");
  1412.     abort(ERRCODE);
  1413.     }
  1414.   k=0;
  1415.   while (k<WQSIZ) *wqptr++ = ptr[k++];
  1416.   }
  1417.  
  1418. delwhile() {
  1419.   if (wqptr > wq) wqptr=wqptr-WQSIZ;
  1420.   }
  1421.  
  1422. readwhile(ptr) int *ptr; {
  1423.   if (ptr <= wq) {
  1424.     error("out of context");
  1425.     return 0;
  1426.     }
  1427.   else return (ptr-WQSIZ);
  1428.  }
  1429.  
  1430. white() {
  1431. #ifdef DYNAMIC
  1432.   /* test for stack/prog overlap at deepest nesting */
  1433.   /* primary -> symname -> blanks -> white */
  1434.   avail(YES);  /* abort on stack/symbol table overflow */
  1435. #endif
  1436.   return ((*lptr<= ' ') & (*lptr!=NULL));
  1437.   }
  1438.  
  1439. gch() {
  1440.   int c;
  1441.   if(c=ch) bump(1);
  1442.   return c;
  1443.   }
  1444.  
  1445. bump(n) int n; {
  1446.   if(n) lptr=lptr+n;
  1447.   else  lptr=line;
  1448.   if(ch = nch = *lptr) nch = *(lptr+1);
  1449.   }
  1450.  
  1451. kill() {
  1452.   *line=0;
  1453.   bump(0);
  1454.   }
  1455.  
  1456. inbyte()  {
  1457.   while(ch==0) {
  1458.     if (eof) return 0;
  1459.     preprocess();
  1460.     }
  1461.   return gch();
  1462.   }
  1463.  
  1464. inline() {           /* numerous revisions */
  1465.   int k,unit;
  1466.   poll(1);           /* allow operator interruption */
  1467.   if (input==EOF) openfile();
  1468.   if(eof) return;
  1469.   if((unit=input2)==EOF) unit=input;
  1470.   if(fgets(line, LINEMAX, unit)==NULL) {
  1471.     fclose(unit);
  1472.     if(input2!=EOF) input2=EOF;
  1473.     else input=EOF;
  1474.     *line=NULL;
  1475.     }
  1476.   else if(listfp) {
  1477.     if(listfp==output) cout(';', output);
  1478.     sout(line, listfp);
  1479.     }
  1480.   bump(0);
  1481.   }
  1482.  
  1483. >>> CC22.C 6770
  1484. ifline() {
  1485.   while(1) {
  1486.     inline();
  1487.     if(eof) return;
  1488.     if(match("#ifdef")) {
  1489.       ++iflevel;
  1490.       if(skiplevel) continue;
  1491.       symname(msname, NO);
  1492.       if(search(msname, macn, NAMESIZE+2, MACNEND, MACNBR, 0)==0)
  1493.         skiplevel=iflevel;
  1494.       continue;
  1495.       }
  1496.     if(match("#ifndef")) {
  1497.       ++iflevel;
  1498.       if(skiplevel) continue;
  1499.       symname(msname, NO);
  1500.       if(search(msname, macn, NAMESIZE+2, MACNEND, MACNBR, 0))
  1501.         skiplevel=iflevel;
  1502.       continue;
  1503.       }
  1504.     if(match("#else")) {
  1505.       if(iflevel) {
  1506.         if(skiplevel==iflevel) skiplevel=0;
  1507.         else if(skiplevel==0)  skiplevel=iflevel;
  1508.         }
  1509.       else noiferr();
  1510.       continue;
  1511.       }
  1512.     if(match("#endif")) {
  1513.       if(iflevel) {
  1514.         if(skiplevel==iflevel) skiplevel=0;
  1515.         --iflevel;
  1516.         }
  1517.       else noiferr();
  1518.       continue;
  1519.       }
  1520.     if(skiplevel) continue;
  1521. #ifdef OLDCC
  1522.     if((listfp!=0) & (*line!=NULL)) {
  1523.       if(listfp==output) cout(';', output);
  1524.       sout(line, listfp);                   /*19*/
  1525.       }
  1526.     if(ch==NEWLINE) continue;
  1527. #else
  1528.     if(ch==0) continue;
  1529.     break;
  1530.     }
  1531.   }
  1532.  
  1533. keepch(c)  char c; {
  1534.   if(pptr<LINEMAX) pline[++pptr]=c;
  1535.   }
  1536.  
  1537. preprocess() {
  1538.   int k;
  1539.   char c;
  1540.   if(ccode) {
  1541.     line=mline;
  1542.     ifline();
  1543.     if(eof) return;
  1544.     }
  1545.   else {
  1546.     line=pline;
  1547.     inline();
  1548.     return;
  1549.     }
  1550.   pptr = -1;
  1551.   while(ch != NEWLINE && ch) {
  1552.     if(white()) {
  1553.       keepch(' ');
  1554.       while(white()) gch();
  1555.       }
  1556.     else if(ch=='"') {
  1557.       keepch(ch);
  1558.       gch();
  1559.       while((ch!='"')|((*(lptr-1)==92)&(*(lptr-2)!=92))) {
  1560.         if(ch==NULL) {
  1561.           error("no quote");
  1562.           break;
  1563.           }
  1564.         keepch(gch());
  1565.         }
  1566.       gch();
  1567.       keepch('"');
  1568.       }
  1569.     else if(ch==39) {
  1570.       keepch(39);
  1571.       gch();
  1572.       while((ch!=39)|((*(lptr-1)==92)&(*(lptr-2)!=92))) {
  1573.         if(ch==NULL) {
  1574.           error("no apostrophe");
  1575.           break;
  1576.           }
  1577.         keepch(gch());
  1578.         }
  1579.       gch();
  1580.       keepch(39);
  1581.       }
  1582.     else if((ch=='/')&(nch=='*')) {
  1583.       bump(2);
  1584.       while(((ch=='*')&(nch=='/'))==0) {
  1585.         if(ch) bump(1);
  1586.         else {
  1587.           ifline();
  1588.           if(eof) break;
  1589.           }
  1590.         }
  1591.       bump(2);
  1592.       }
  1593.     else if(an(ch)) {
  1594.       k=0;
  1595.       while((an(ch)) & (k<NAMEMAX)) {
  1596.         msname[k++]=ch;
  1597.         gch();
  1598.         }
  1599.       msname[k]=NULL;
  1600.       if(search(msname, macn, NAMESIZE+2, MACNEND, MACNBR, 0)) {
  1601.         k=getint(cptr+NAMESIZE, 2);
  1602.         while(c=macq[k++]) keepch(c);
  1603.         while(an(ch)) gch();
  1604.         }
  1605.       else {
  1606.         k=0;
  1607.         while(c=msname[k++]) keepch(c);
  1608.         }
  1609.       }
  1610.     else keepch(gch());
  1611.     }
  1612.   if(pptr>=LINEMAX) error("line too long");
  1613.   keepch(NULL);
  1614.   line=pline;
  1615.   bump(0);
  1616.   }
  1617.  
  1618. noiferr() {
  1619.   error("no matching #if...");
  1620.   errflag=0;
  1621.   }
  1622.  
  1623. addmac() {
  1624.   int k;
  1625.   if(symname(msname, NO)==0) {
  1626.     illname();
  1627.     kill();
  1628.     return;
  1629.     }
  1630.   k=0;
  1631.   if(search(msname, macn, NAMESIZE+2, MACNEND, MACNBR, 0)==0) {
  1632.     if(cptr2=cptr) while(*cptr2++ = msname[k++]);
  1633.     else {
  1634.       error("macro name table full");
  1635.       return;
  1636.       }
  1637.     }
  1638.   putint(macptr, cptr+NAMESIZE, 2);
  1639.   while(white()) gch();
  1640.   while(putmac(gch()));
  1641.   if(macptr>=MACMAX) {
  1642.     error("macro string queue full"); abort(ERRCODE);
  1643.     }
  1644.   }
  1645.  
  1646. putmac(c)  char c; {
  1647.   macq[macptr]=c;
  1648.   if(macptr<MACMAX) ++macptr;
  1649.   return c;
  1650.   }
  1651.  
  1652. /*
  1653. ** search for symbol match
  1654. ** on return cptr points to slot found or empty slot
  1655. */
  1656. search(sname, buf, len, end, max, off)
  1657.   char *sname, *buf, *end;  int len, max, off; {
  1658.   cptr=cptr2=buf+((hash(sname)%(max-1))*len);
  1659.   while(*cptr != NULL) {
  1660.     if(astreq(sname, cptr+off, NAMEMAX)) return 1;
  1661.     if((cptr=cptr+len) >= end) cptr=buf;
  1662.     if(cptr == cptr2) return (cptr=0);
  1663.     }
  1664.   return 0;
  1665.   }
  1666.  
  1667. hash(sname) char *sname; {
  1668.   int i, c;
  1669.   i=0;
  1670.   while(c = *sname++) i=(i<<1)+c;
  1671.   return i;
  1672.   }
  1673.  
  1674. outdec(number)  int number; {
  1675.   int k,zs;
  1676.   char c, *q, *r;
  1677.   zs = 0;
  1678.   k=10000;
  1679.   if (number<0) {
  1680.     number=(-number);
  1681.     outbyte('-');
  1682.     }
  1683.   while (k>=1) {
  1684.     q=0; r=number;
  1685.     while(r >= k) {++q; r = r - k;}
  1686.     c = q + '0';
  1687.     if ((c!='0')|(k==1)|(zs)) {
  1688.       zs=1;
  1689.       outbyte(c);
  1690.       }
  1691.     number=r;
  1692.     k=k/10;
  1693.     }
  1694.   }
  1695.  
  1696. ol(ptr)  char ptr[];  {
  1697.   ot(ptr);
  1698.   nl();
  1699.   }
  1700.  
  1701. ot(ptr) char ptr[]; {
  1702.   outstr(ptr);
  1703.   }
  1704.  
  1705. outstr(ptr) char ptr[]; {
  1706.   poll(1); /* allow program interruption */
  1707.   /* must work with symbol table names terminated by length */
  1708.   while(*ptr >= ' ') outbyte(*ptr++);
  1709.   }
  1710.  
  1711. /*
  1712. ** output a name so that it can't look like a reserved word
  1713. */
  1714. outname(ptr) char ptr[]; {
  1715.   outstr("_");
  1716.   while(*ptr >= ' ') outbyte(toupper(*ptr++));
  1717.   }
  1718.  
  1719. outbyte(c) char c; {
  1720.   cout(c,output);
  1721.   return c;
  1722.   }
  1723.  
  1724. cout(c, fd) char c; int fd; {
  1725.   if(fputc(c, fd)==EOF) xout();
  1726.   }
  1727.  
  1728. sout(string, fd) char *string; int fd; {
  1729.   if(fputs(string, fd)==EOF) xout();
  1730.   }
  1731.  
  1732. lout(line, fd) char *line; int fd; {
  1733.   sout(line, fd);
  1734.   cout(NEWLINE, fd);
  1735.   }
  1736.  
  1737. xout() {
  1738.   fputs("output error", stderr);
  1739.   abort(ERRCODE);
  1740.   }
  1741.  
  1742. nl() {
  1743.   outbyte(NEWLINE);
  1744.   }
  1745.  
  1746. col() {
  1747. #ifdef COL
  1748.   outbyte(':');
  1749. #endif
  1750.   }
  1751.  
  1752. error(msg) char msg[]; {
  1753.   if(errflag) return; else errflag=1;
  1754.   lout(line, stderr);
  1755.   errout(msg, stderr);
  1756.   if(alarm) fputc(7, stderr);
  1757.   if(pause) while(fgetc(stderr) != NEWLINE);
  1758.   if(listfp>0) errout(msg, listfp);
  1759.   }
  1760.  
  1761. errout(msg, fp) char msg[]; int fp; {
  1762.   int k; k=line+2;
  1763.   while(k++ <= lptr) cout(' ', fp);
  1764.   lout("/\\", fp);
  1765.   sout("**** ", fp); lout(msg, fp);
  1766.   }
  1767.  
  1768. streq(str1,str2)  char str1[],str2[]; {
  1769.   int k;
  1770.   k=0;
  1771.   while (str2[k]) {
  1772.     if ((str1[k])!=(str2[k])) return 0;
  1773.     ++k;
  1774.     }
  1775.   return k;
  1776.  }
  1777.  
  1778. astreq(str1,str2,len)  char str1[],str2[];int len; {
  1779.   int k;
  1780.   k=0;
  1781.   while (k<len) {
  1782.     if ((str1[k])!=(str2[k]))break;
  1783.     /*
  1784.     ** must detect end of symbol table names terminated by
  1785.     ** symbol length in binary
  1786.     */
  1787.     if(str1[k] < ' ') break;
  1788.     if(str2[k] < ' ') break;
  1789.     ++k;
  1790.     }
  1791.   if (an(str1[k]))return 0;
  1792.   if (an(str2[k]))return 0;
  1793.   return k;
  1794.  }
  1795.  
  1796. match(lit)  char *lit; {
  1797.   int k;
  1798.   blanks();
  1799.   if (k=streq(lptr,lit)) {
  1800.     bump(k);
  1801.     return 1;
  1802.     }
  1803.   return 0;
  1804.   }
  1805.  
  1806. amatch(lit,len)  char *lit;int len; {
  1807.   int k;
  1808.   blanks();
  1809.   if (k=astreq(lptr,lit,len)) {
  1810.     bump(k);
  1811.     while(an(ch)) inbyte();
  1812.     return 1;
  1813.     }
  1814.   return 0;
  1815.  }
  1816.  
  1817. nextop(list) char *list; {
  1818.   char op[4];
  1819.   opindex=0;
  1820.   blanks();
  1821.   while(1) {
  1822.     opsize=0;
  1823.     while(*list > ' ') op[opsize++] = *list++;
  1824.     op[opsize]=0;
  1825.     if(opsize=streq(lptr, op))
  1826.       if((*(lptr+opsize) != '=')&
  1827.          (*(lptr+opsize) != *(lptr+opsize-1)))
  1828.          return 1;
  1829.     if(*list) {
  1830.       ++list;
  1831.       ++opindex;
  1832.       }
  1833.     else return 0;
  1834.     }
  1835.   }
  1836.  
  1837. blanks() {
  1838.   while(1) {
  1839.     while(ch) {
  1840.       if(white()) gch();
  1841.       else return;
  1842.       }
  1843.     if(line==mline) return;
  1844.     preprocess();
  1845.     if(eof)break;
  1846.     }
  1847.   }
  1848.  
  1849. >>> CC3.C 902
  1850. /*
  1851. ** Small-C Compiler Part 3
  1852. */
  1853. #include <stdio.h>
  1854. #include "cc.def"
  1855.  
  1856. extern char
  1857. #ifdef DYNAMIC
  1858.  *litq,
  1859. #else
  1860.   litq[LITABSZ],
  1861. #endif
  1862.  *glbptr, *lptr,  ssname[NAMESIZE],  quote[2];
  1863. extern int
  1864.   ch,  csp,  litlab,  litptr,  nch,  op[16],  op2[16],
  1865.   oper,  opindex,  opsize, *stagenext;
  1866.  
  1867.                     /* entries in lval[] */
  1868. #define SYMTBL  0   /* symbol table address, else 0 for constant */
  1869. #define TYPEIND 1   /* type of indirect obj to fetch, else 0 for static */
  1870. #define TYPEPA  2   /* type of pointer or array, else 0 for all other */
  1871. #define CONEXP  3   /* true if constant expression */
  1872. #define CONVAL  4   /* value of constant expression */
  1873. #define REG2    5   /* true if secondary register altered*/
  1874. #define OPER    6   /* code of highest/last binary operator */
  1875. #define STAGE   7   /* stage address of "oper 0" code, else 0 */
  1876.  
  1877. #include "cc31.c"
  1878. #include "cc32.c"
  1879. #include "cc33.c"
  1880.  
  1881. >>> CC31.C 8321
  1882. /*
  1883. ** lval[0] - symbol table address, else 0 for constant
  1884. ** lval[1] - type of indirect obj to fetch, else 0 for static
  1885. ** lval[2] - type of pointer or array, else 0 for all other
  1886. ** lval[3] - true if constant expression
  1887. ** lval[4] - value of constant expression (+ auxiliary uses)
  1888. ** lval[5] - true if secondary register altered
  1889. ** lval[6] - code of highest/last binary operator
  1890. ** lval[7] - stage address of "oper 0" code, else 0
  1891. */
  1892.  
  1893. /*
  1894. ** skim over terms adjoining || and && operators
  1895. */
  1896. skim(opstr, testfunc, dropval, endval, hier, lval)
  1897.   char *opstr;
  1898.   int testfunc, dropval, endval, (*hier)(), lval[]; {
  1899.   int k, hits, droplab, endlab;
  1900.   hits=0;
  1901.   while(1) {
  1902.     k=plnge1(hier, lval);
  1903.     if(nextop(opstr)) {
  1904.       bump(opsize);
  1905.       if(hits==0) {
  1906.         hits=1;
  1907.         droplab=getlabel();
  1908.         }
  1909.       dropout(k, testfunc, droplab, lval);
  1910.       }
  1911.     else if(hits) {
  1912.       dropout(k, testfunc, droplab, lval);
  1913.       gen_code(_IMMED, endval);
  1914.       gen_code(_JUMP, endlab=getlabel());
  1915.       gen_code(_LABEL, droplab);
  1916.       gen_code(_IMMED, dropval);
  1917.       gen_code(_LABEL, endlab);
  1918.       lval[TYPEIND] = lval[TYPEPA] = lval[CONEXP] =
  1919.       lval[CONVAL] = lval[STAGE] = 0;
  1920.       return 0;
  1921.       }
  1922.     else return k;
  1923.     }
  1924.   }
  1925.  
  1926. /*
  1927. ** test for early dropout from || or && evaluations
  1928. */
  1929. dropout(k, testfunc, exit1, lval)
  1930.   int k, testfunc, exit1, lval[]; {
  1931.   if(k) rvalue(lval);
  1932.   else if(lval[CONEXP]) gen_code(_IMMED, lval[CONVAL]);
  1933.   gen_code(testfunc, exit1);          /* jumps on false */
  1934.   }
  1935.  
  1936. /*
  1937. ** plunge to a lower level
  1938. */
  1939. plnge(opstr, opoff, hier, lval)
  1940.   char *opstr;
  1941.   int opoff, (*hier)(), lval[]; {
  1942.   int k, lval2[8];
  1943.   k=plnge1(hier, lval);
  1944.   if(nextop(opstr)==0) return k;
  1945.   if(k) rvalue(lval);
  1946.   while(1) {
  1947.     if(nextop(opstr)) {
  1948.       bump(opsize);
  1949.       opindex=opindex+opoff;
  1950.       plnge2(op[opindex], op2[opindex], hier, lval, lval2);
  1951.       }
  1952.     else return 0;
  1953.     }
  1954.   }
  1955.  
  1956. /*
  1957. ** unary plunge to lower level
  1958. */
  1959. plnge1(hier, lval) int (*hier)(), lval[]; {
  1960.   int *before, *start;
  1961.   int k;
  1962.   setstage(&before, &start);
  1963.   k=(*hier)(lval);
  1964.   if(lval[CONEXP]) clearstage(before,0);  /* load constant later */
  1965.   return k;
  1966.   }
  1967.  
  1968. /*
  1969. ** binary plunge to lower level
  1970. */
  1971. plnge2(oper, oper2, hier, lval, lval2)
  1972.   int oper, oper2, (*hier)(), lval[], lval2[]; {
  1973.   int *before, *start;
  1974.   setstage(&before, &start);
  1975.   lval[REG2]=1;            /* flag secondary register used */
  1976.   lval[STAGE]=0;           /* flag as not "... oper 0" syntax */
  1977.   if(lval[CONEXP]) {        /* constant on left side not yet loaded */
  1978.     if(plnge1(hier, lval2)) rvalue(lval2);
  1979.     if(lval[CONVAL]==0) lval[STAGE]=stagenext;
  1980.     gen_code(_IMMED2, lval[CONVAL]<<dbltest(oper, lval2, lval));
  1981.     }
  1982.   else {                   /* non-constant on left side */
  1983.     gen_code(_PUSH, 0);
  1984.     if(plnge1(hier, lval2)) rvalue(lval2);
  1985.     if(lval2[CONEXP]) {     /* constant on right side */
  1986.       if(lval2[CONVAL]==0) lval[STAGE]=start;
  1987.       csp+=2;
  1988.       clearstage(before, 0);
  1989.       if(oper==_ADD) {     /* may test other commutative operators */
  1990.         gen_code(_IMMED2, lval2[CONVAL]<<dbltest(oper, lval, lval2));
  1991.         }
  1992.       else {
  1993.         gen_code(_MOVE, 0);
  1994.         gen_code(_IMMED, lval2[CONVAL]<<dbltest(oper, lval, lval2));
  1995.         }
  1996.       }
  1997.     else {                 /* non-constants on both sides */
  1998.       gen_code(_POP, 0);
  1999.       if((oper==_ADD)|(oper==_SUB)) {
  2000.         if(dbltest(oper, lval, lval2)) gen_code(_DBL, 0);
  2001.         if(dbltest(oper, lval2, lval)) gen_code(_DBL2, 0);
  2002.         }
  2003.       }
  2004.     }
  2005.   if(oper) {
  2006.     if(lval[CONEXP]=lval[CONEXP]&lval2[CONEXP]) {
  2007.       lval[CONVAL]=calc(lval[CONVAL], oper, lval2[CONVAL]);
  2008.       clearstage(before, 0);  
  2009.       lval[REG2]=0;
  2010.       }
  2011.     else {
  2012.       if((lval[TYPEPA]==0)&(lval2[TYPEPA]==0)) {  /* neither is a pointer */
  2013.         gen_code(oper, 0);
  2014.         lval[OPER]=oper;    /* identify the operator */
  2015.         }
  2016.       else {
  2017.         gen_code(oper2, 0);
  2018.         lval[OPER]=oper2;   /* identify the operator */
  2019.         }
  2020.       }
  2021.     if(oper==_SUB) {
  2022.       /* if subtracting two pointers to integers */
  2023.       if((lval[TYPEPA]==CINT)&(lval2[TYPEPA]==CINT)) {
  2024.         gen_code(_SWAP, 0);
  2025.         gen_code(_IMMED, 1);
  2026.         gen_code(_ASR, 0);  /** div by 2 **/
  2027.         }
  2028.       }
  2029.     if((oper==_SUB)|(oper==_ADD)) result(lval, lval2);
  2030.     }
  2031.   }
  2032.  
  2033. calc(left, oper, right) int left, oper, right; {
  2034.   switch(oper) {
  2035.     case _OR:   return (left  |  right);
  2036.     case _XOR:  return (left  ^  right);
  2037.     case _AND:  return (left  &  right);
  2038.     case _EQ:   return (left  == right);
  2039.     case _NE:   return (left  != right);
  2040.     case _LE:   return (left  <= right);
  2041.     case _GE:   return (left  >= right);
  2042.     case _LT:   return (left  <  right);
  2043.     case _GT:   return (left  >  right);
  2044.     case _ASR:  return (left  >> right);
  2045.     case _ASL:  return (left  << right);
  2046.     case _ADD:  return (left  +  right);
  2047.     case _SUB:  return (left  -  right);
  2048.     case _MULT: return (left  *  right);
  2049.     case _DIV:  return (left  /  right);
  2050.     case _MOD:  return (left  %  right);
  2051.     default:     return 0;
  2052.     }
  2053.   }
  2054.  
  2055. expression(const, val) int *const, *val;  {
  2056.   int lval[8];
  2057.   if(hier1(lval)) rvalue(lval);
  2058.   if(lval[CONEXP]) {
  2059.     *const=1;
  2060.     *val=lval[CONVAL];
  2061.     }
  2062.   else *const=0;
  2063.   }
  2064.  
  2065. hier1(lval) int lval[];  {
  2066.   int k, lval2[8], lval3[2], oper;
  2067.   k=plnge1(hier2, lval);
  2068.   if(lval[CONEXP]) gen_code(_IMMED, lval[CONVAL]);
  2069.        if(match("|="))  oper=_OR;
  2070.   else if(match("^="))  oper=_XOR;
  2071.   else if(match("&="))  oper=_AND;
  2072.   else if(match("+="))  oper=_ADD;
  2073.   else if(match("-="))  oper=_SUB;
  2074.   else if(match("*="))  oper=_MULT;
  2075.   else if(match("/="))  oper=_DIV;
  2076.   else if(match("%="))  oper=_MOD;
  2077.   else if(match(">>=")) oper=_ASR;
  2078.   else if(match("<<=")) oper=_ASL;
  2079.   else if(match("="))   oper=0;
  2080.   else return k;
  2081.   if(k==0) {needlval(); return 0;}
  2082.   lval3[SYMTBL]  = lval[SYMTBL];
  2083.   lval3[TYPEIND] = lval[TYPEIND];
  2084.   if(lval[TYPEIND]) {  /* if we have a pointer to the variable, save it.*/
  2085.     if(oper) {
  2086.       gen_code(_PUSH, 0);
  2087.       rvalue(lval);
  2088.       }
  2089.     plnge2(oper, oper, hier1, lval, lval2);
  2090.     if(oper) gen_code(_POP, 0);
  2091.     }
  2092.   else {
  2093.     if(oper) {
  2094.       rvalue(lval);
  2095.       plnge2(oper, oper, hier1, lval, lval2);
  2096.       }
  2097.     else {
  2098.       if(hier1(lval2)) rvalue(lval2);
  2099.       lval[REG2]=lval2[REG2];
  2100.       }
  2101.     }
  2102.   store(lval3);
  2103.   return 0;
  2104.   }
  2105.  
  2106. hier2(lval)  int lval[]; {
  2107.   int k, falselab, endlab;
  2108.   int *before, *after;
  2109.   int const, retconst, retval;
  2110.   retconst = NO; /* assume non-constant */
  2111.   k = plnge1(hier3, lval);
  2112.   if (lval[CONEXP] && lval[CONVAL]) const = 1;
  2113.   else if (lval[CONEXP] && !lval[CONVAL]) const = -1;
  2114.   else const = 0;
  2115.   if (match("?")==0) return k;
  2116.   if (!const) dropout(k, _NE0, falselab = getlabel(), lval);
  2117.   setstage(&before, &after);    /* prepare to delete code */
  2118.   if (plnge1(hier3, lval)) rvalue(lval);
  2119.   else if (lval[CONEXP]) gen_code(_IMMED, lval[CONVAL]);
  2120.   if (const<0) clearstage(before, 0); /* if false, delete 'then' expr */
  2121.   else if (const>0) {
  2122.     retconst = lval[CONEXP];
  2123.     retval = lval[CONVAL];
  2124.     }
  2125.   needtoken(":");
  2126.   if (!const) {
  2127.     gen_code(_JUMP, endlab = getlabel());
  2128.     gen_code(_LABEL, falselab);
  2129.     }
  2130.   setstage(&before, &after);
  2131.   if (plnge1(hier3, lval)) rvalue(lval);
  2132.   else if (lval[CONEXP]) gen_code(_IMMED, lval[CONVAL]);
  2133.   if (const>0) clearstage(before, 0); /* if true, delete 'else' expr */
  2134.   else if (const<0) {
  2135.     retconst = lval[CONEXP];
  2136.     retval = lval[CONVAL];
  2137.     }
  2138.   if (!const) gen_code(_LABEL, endlab);
  2139.   lval[CONEXP] = retconst;
  2140.   lval[CONVAL] = retval;
  2141.   lval[TYPEIND]=lval[TYPEPA]=lval[STAGE]=0;
  2142.   return 0;
  2143.   }
  2144.  
  2145. hier3(lval)  int lval[]; {
  2146.   return skim("||", _EQ0, 1, 0, hier4, lval);
  2147.   }
  2148.  
  2149. hier4(lval)  int lval[]; {
  2150.   return skim("&&", _NE0, 0, 1, hier5, lval);
  2151.   }
  2152.  
  2153. hier5(lval)  int lval[]; {
  2154.   return plnge("|", 0, hier6, lval);
  2155.   }
  2156.  
  2157. hier6(lval)  int lval[]; {
  2158.   return plnge("^", 1, hier7, lval);
  2159.   }
  2160.  
  2161. hier7(lval)  int lval[]; {
  2162.   return plnge("&", 2, hier8, lval);
  2163.   }
  2164.  
  2165. hier8(lval)  int lval[];  {
  2166.   return plnge("== !=", 3, hier9, lval);
  2167.   }
  2168.  
  2169. hier9(lval)  int lval[];  {
  2170.   return plnge("<= >= < >", 5, hier10, lval);
  2171.   }
  2172.  
  2173. hier10(lval)  int lval[];  {
  2174.   return plnge(">> <<", 9, hier11, lval);
  2175.   }
  2176.  
  2177. hier11(lval)  int lval[];  {
  2178.   return plnge("+ -", 11, hier12, lval);
  2179.   }
  2180.  
  2181. hier12(lval)  int lval[];  {
  2182.   return plnge("* / %", 13, hier13, lval);
  2183.   }
  2184.  
  2185. >>> CC32.C 6090
  2186. hier13(lval)  int lval[];  {
  2187.   int k;
  2188.   char *ptr;
  2189.   if(match("++")) {                   /* ++lval */
  2190.     if(hier13(lval)==0) {
  2191.       needlval();
  2192.       return 0;
  2193.       }
  2194.     step(_INC, lval, 0);
  2195.     return 0;
  2196.     }
  2197.   else if(match("--")) {              /* --lval */
  2198.     if(hier13(lval)==0) {
  2199.       needlval();
  2200.       return 0;
  2201.       }
  2202.     step(_DEC, lval, 0);
  2203.     return 0;
  2204.     }
  2205.   else if (match("~")) {              /* ~ */
  2206.     if(hier13(lval)) rvalue(lval);
  2207.     gen_code(_COM, 0);
  2208.     lval[CONVAL] = ~ lval[CONVAL];
  2209.     return (lval[STAGE]=0);
  2210.     }
  2211.   else if (match("!")) {              /* ! */
  2212.     if(hier13(lval)) rvalue(lval);
  2213.     gen_code(_LNEG, 0);
  2214.     lval[CONVAL] = ! lval[CONVAL];
  2215.     return (lval[STAGE]=0);
  2216.     }
  2217.   else if (match("-")) {              /* unary - */
  2218.     if(hier13(lval)) rvalue(lval);
  2219.     gen_code(_NEG, 0);
  2220.     lval[CONVAL] = -lval[CONVAL];
  2221.     return (lval[STAGE]=0);
  2222.     }
  2223.   else if(match("*")) {               /* unary * */
  2224.     if(hier13(lval)) rvalue(lval);
  2225.     if(ptr=lval[SYMTBL]) lval[TYPEIND]=ptr[TYPE];
  2226.     else lval[TYPEIND]=CINT;
  2227.     lval[TYPEPA]=0;    /* flag as not pointer or array */
  2228.     lval[CONEXP]=0;    /* flag as not constant */
  2229.     lval[CONVAL]=1;    /* omit rvalue() on func call */
  2230.     lval[STAGE]=0;
  2231.     return 1;
  2232.     }
  2233.   else if(match("sizeof(")) {         /* sizeof() */
  2234.     int *before, *start;
  2235.     setstage(&before, &start);
  2236.     k=hier13(lval);
  2237.     clearstage(before, 0);
  2238.     needtoken(")");
  2239.     lval[CONEXP]=1;
  2240.     if (lval[TYPEPA]) lval[CONVAL]=CINT>>2;
  2241.     else lval[CONVAL]=lval[TYPEIND]>>2;
  2242.     lval[TYPEPA]=lval[TYPEIND]=lval[SYMTBL]=0;
  2243.     return 0;
  2244.     }
  2245.   else if(match("&")) {               /* unary & */
  2246.     if(hier13(lval)==0) {
  2247.       error("illegal address");
  2248.       return 0;
  2249.       }
  2250.     ptr=lval[SYMTBL];
  2251.     lval[TYPEPA]=ptr[TYPE];
  2252.     if(lval[TYPEIND]) return 0;
  2253.                                       /* global & non-array */
  2254.     gen_code(_OFFSET, ptr);
  2255.     lval[TYPEIND]=ptr[TYPE];
  2256.     return 0;
  2257.     }
  2258.   else {
  2259.     k=hier14(lval);
  2260.     if(match("++")) {                 /* lval++ */
  2261.       if(k==0) {
  2262.         needlval();
  2263.         return 0;
  2264.         }
  2265.       step(_INC, lval, _DEC);
  2266.       return 0;
  2267.       }
  2268.     else if(match("--")) {            /* lval-- */
  2269.       if(k==0) {
  2270.         needlval();
  2271.         return 0;
  2272.         }
  2273.       step(_DEC, lval, _INC);
  2274.       return 0;
  2275.       }
  2276.     else return k;
  2277.     }
  2278.   }
  2279.  
  2280. hier14(lval)  int *lval; {
  2281.   int k, const, val, lval2[8];
  2282.   char *ptr, *before, *start;
  2283.   k=primary(lval);
  2284.   ptr=lval[SYMTBL];
  2285.   blanks();
  2286.   if((ch=='[')|(ch=='(')) {
  2287.     lval[REG2]=1;            /* secondary register will be used */
  2288.     while(1) {
  2289.       if(match("[")) {                /* [subscript] */
  2290.         if(ptr==0) {
  2291.           error("can't subscript");
  2292.           junk();
  2293.           needtoken("]");
  2294.           return 0;
  2295.           }
  2296.         else if(ptr[IDENT]==POINTER) rvalue(lval);
  2297.         else if(ptr[IDENT]!=ARRAY) {
  2298.           error("can't subscript");
  2299.           k=0;
  2300.           }
  2301.         setstage(&before, &start);
  2302.         lval2[CONEXP]=0;
  2303.         plnge2(0, 0, hier1, lval2, lval2); /* lval2 deadend */
  2304.         needtoken("]");
  2305.         if(lval2[CONEXP]) {
  2306.           clearstage(before, 0);
  2307.           if(lval2[CONVAL]) {    /* only add if non-zero */
  2308.             if(ptr[TYPE]==CINT) gen_code(_IMMED2, lval2[CONVAL]<<LBPW);
  2309.             else                gen_code(_IMMED2, lval2[CONVAL]);
  2310.             gen_code(_ADD, 0);
  2311.             }
  2312.           }
  2313.         else {
  2314.           if(ptr[TYPE]==CINT) gen_code(_DBL, 0);
  2315.           gen_code(_ADD, 0);
  2316.           }
  2317.         lval[TYPEPA]=0;
  2318.         lval[TYPEIND]=ptr[TYPE];
  2319.         k=1;
  2320.         }
  2321.       else if(match("(")) {                /* function(...) */
  2322.         if(ptr==0) callfunction(0);
  2323.         else if(ptr[IDENT]!=FUNCTION) {
  2324.           if(k && !lval[CONVAL]) rvalue(lval);
  2325.           callfunction(0);
  2326.           }
  2327.         else callfunction(ptr);
  2328.         k=lval[SYMTBL]=lval[CONEXP]=lval[CONVAL]=0;
  2329.         }
  2330.       else return k;
  2331.       }
  2332.     }
  2333.   if(ptr==0) return k;
  2334.   if(ptr[IDENT]==FUNCTION) {
  2335.     gen_code(_OFFSET, ptr);
  2336.     lval[SYMTBL]=0;
  2337.     return 0;
  2338.     }
  2339.   return k;
  2340.   }
  2341.  
  2342. primary(lval)  int *lval; {
  2343.   char *ptr, sname[NAMESIZE];
  2344.   int k;
  2345.   if(match("(")) {          /* (expression,...) */
  2346.     do k=hier1(lval); while(match(","));
  2347.     needtoken(")");
  2348.     return k;
  2349.     }
  2350.   putint(0, lval, 8<<LBPW); /* clear lval array */
  2351.   if(symname(sname, YES)) {
  2352.     if(ptr=findloc(sname)) {
  2353. #ifdef STGOTO
  2354.       if(ptr[IDENT]==LABEL) {
  2355.         experr();
  2356.         return 0;
  2357.         }
  2358. #endif
  2359.       gen_code(_GSTK, ptr);
  2360.       lval[SYMTBL]=ptr;
  2361.       lval[TYPEIND]=ptr[TYPE];
  2362.       if(ptr[IDENT]==POINTER) {
  2363.         lval[TYPEIND]=CINT;
  2364.         lval[TYPEPA]=ptr[TYPE];
  2365.         }
  2366.       if(ptr[IDENT]==ARRAY) {
  2367.         lval[TYPEPA]=ptr[TYPE];
  2368.         return 0;
  2369.         }
  2370.       else return 1;
  2371.       }
  2372.     if(ptr=findglb(sname))
  2373.       if(ptr[IDENT]!=FUNCTION) {
  2374.         lval[SYMTBL]=ptr;
  2375.         lval[TYPEIND]=0;
  2376.         if(ptr[IDENT]!=ARRAY) {
  2377.           if(ptr[IDENT]==POINTER) lval[TYPEPA]=ptr[TYPE];
  2378.           return 1;
  2379.           }
  2380.         gen_code(_OFFSET, ptr);
  2381.         lval[TYPEIND]=lval[TYPEPA]=ptr[TYPE];
  2382.         return 0;
  2383.         }
  2384.     ptr=addsym(sname, FUNCTION, CINT, 0, &glbptr, AUTOEXT);
  2385.     lval[SYMTBL]=ptr;
  2386.     lval[TYPEIND]=0;
  2387.     return 0;
  2388.     }
  2389.   if(constant(lval)==0) experr();
  2390.   return 0;
  2391.   }
  2392.  
  2393. experr() {
  2394.   error("invalid expression");
  2395.   gen_code(_IMMED, 0);
  2396.   junk();
  2397.   }
  2398.  
  2399. callfunction(ptr)  char *ptr; { /* symbol table entry or 0 */
  2400.   int nargs, const, val;
  2401.   nargs=0;
  2402.   blanks();                     /* already saw open paren */
  2403.   while(streq(lptr,")")==0) {
  2404.     if(endst()) break;
  2405.     if(ptr) {
  2406.       expression(&const, &val);
  2407.       gen_code(_PUSH,0);
  2408.       }
  2409.     else {
  2410.       gen_code(_PUSH,0);
  2411.       expression(&const, &val);
  2412.       gen_code(_SWAPSTK, 0);    /* don't push addr */
  2413.       }
  2414.     nargs=nargs+BPW;            /* count args*BPW */
  2415.     if (match(",")==0) break;
  2416.     }
  2417.   needtoken(")");
  2418.   if(streq(ptr+NAME, "CCARGC")==0) loadargc(nargs>>LBPW);
  2419.   if(ptr) gen_code(_CALL, ptr);
  2420.   else gen_code(_CALLSTK, 0);
  2421.   gen_code(_MODSTK, csp+nargs);
  2422.   }
  2423.  
  2424. >>> CC33.C 4768
  2425. /*
  2426. ** true if val1 -> int pointer or int array and val2 not ptr or array
  2427. */
  2428. dbltest(oper, val1,val2) int oper, val1[], val2[]; {
  2429.   if((oper!=_ADD) && (oper!=_SUB)) return 0;
  2430.   if(val1[TYPEPA]!=CINT) return 0;
  2431.   if(val2[TYPEPA]) return 0;
  2432.   return 1;
  2433.   }
  2434.  
  2435. /*
  2436. ** determine type of binary operation
  2437. */
  2438. result(lval, lval2) int lval[], lval2[]; {
  2439.   if((lval[TYPEPA]!=0)&(lval2[TYPEPA]!=0)) {
  2440.     lval[TYPEPA]=0;
  2441.     }
  2442.   else if(lval2[TYPEPA]) {
  2443.     lval[SYMTBL]=lval2[SYMTBL];
  2444.     lval[TYPEIND]=lval2[TYPEIND];
  2445.     lval[TYPEPA] =lval2[TYPEPA];
  2446.     }
  2447.   }
  2448.  
  2449. step(oper, lval, oper2) int oper, lval[], oper2; {
  2450.   rvalue(lval);
  2451.   gen_code(oper, lval[TYPEPA]>>2 ? lval[TYPEPA]>>2 : 1);
  2452.   store(lval);
  2453.   if(oper2) gen_code(oper2, lval[TYPEPA]>>2 ? lval[TYPEPA]>>2 : 1);
  2454.   }
  2455.  
  2456. store(lval)  int lval[]; {
  2457.   char *sym;
  2458.   if(lval[TYPEIND]) {
  2459.     /* putstk */
  2460.     if(lval[TYPEIND]==CCHAR) gen_code(_PCHAR, 0);
  2461.     else gen_code(_PINT, 0);
  2462.     }
  2463.   else {
  2464.     /* putmem */
  2465.     sym = lval[SYMTBL];
  2466.     if((sym[IDENT]!=POINTER)&(sym[TYPE]==CCHAR)) gen_code(_SCHAR, sym);
  2467.     else gen_code(_SINT, sym);
  2468.     }
  2469.   }
  2470.  
  2471. rvalue(lval) int lval[]; {
  2472.   char *sym;
  2473.   if ((lval[SYMTBL]!=0)&(lval[TYPEIND]==0)) {
  2474.     /* getmem */
  2475.     sym = lval[SYMTBL];
  2476.     if((sym[IDENT]!=POINTER)&(sym[TYPE]==CCHAR)) gen_code(_LCHAR, sym);
  2477.     else gen_code(_LINT, sym);
  2478.     }
  2479.   else {
  2480.     /* indirect */
  2481.     if(lval[TYPEIND]==CCHAR) gen_code(_GCHAR, 0);
  2482.     else gen_code(_GINT, 0);
  2483.     }
  2484.   }
  2485.  
  2486. test(label, parens)  int label, parens;  {
  2487.   int lval[8];
  2488.   int *before, *start;
  2489.   if(parens) needtoken("(");
  2490.   while(1) {
  2491.     setstage(&before, &start);
  2492.     if(hier1(lval)) rvalue(lval);
  2493.     if(match(",")) clearstage(before, start);
  2494.     else break;
  2495.     }
  2496.   if(parens) needtoken(")");
  2497.   if(lval[CONEXP]) {         /* constant expression */
  2498.     clearstage(before, 0);
  2499.     if(lval[CONVAL]) return;
  2500.     gen_code(_JUMP, label);
  2501.     return;
  2502.     }
  2503.   if(lval[STAGE]) {         /* stage address of "oper 0" code */
  2504.     switch(lval[OPER]) {    /* operator code */
  2505.       case _EQ:
  2506.       case _ULE: zerojump(_EQ0, label, lval);   break;
  2507.       case _NE:
  2508.       case _UGT: zerojump(_NE0, label, lval);   break;
  2509.       case _GT:  zerojump(_GT0, label, lval);   break;
  2510.       case _GE:  zerojump(_GE0, label, lval);   break;
  2511.       case _UGE: clearstage(lval[STAGE], 0);    break;
  2512.       case _LT:  zerojump(_LT0, label, lval);   break;
  2513.       case _ULT: zerojump(_ULT0, label, lval);  break;
  2514.       case _LE:  zerojump(_LE0, label, lval);   break;
  2515.       default:   gen_code(_TESTJUMP, label);    break;
  2516.       }
  2517.     }
  2518.   else gen_code(_TESTJUMP, label);
  2519.   clearstage(before, start);
  2520.   }
  2521.  
  2522. constexpr(val) int *val; {
  2523.   int const;
  2524.   int *before, *start;
  2525.   setstage(&before, &start);
  2526.   expression(&const, val);
  2527.   clearstage(before, 0);  /* scratch generated code */
  2528.   if(const==0) error("must be constant expression");
  2529.   return const;
  2530.   }
  2531.  
  2532. constant(lval)  int lval[]; {
  2533.   lval += CONEXP;
  2534.   *lval=1;       /* assume it will be a constant */
  2535.   if (number(++lval)) gen_code(_IMMED, *lval);
  2536.   else if (pstr(lval)) gen_code(_IMMED, *lval);
  2537.   else if (qstr(lval)) {
  2538.     *(lval-1)=0; /* nope, it's a string address */
  2539.     gen_code(_STRING, *lval);
  2540.     }
  2541.   else return 0;
  2542.   return 1;
  2543.   }
  2544.  
  2545. number(val)  int val[]; {
  2546.   int k, minus;
  2547.   k=minus=0;
  2548.   while(1) {
  2549.     if(match("+")) ;
  2550.     else if(match("-")) minus=1;
  2551.     else break;
  2552.     }
  2553.   if(isdigit(ch)==0) return 0;
  2554.   if (ch=='0') {
  2555.     while(ch == '0') inbyte();
  2556.     if (toupper(ch)=='X') {
  2557.       inbyte();
  2558.       while(isxdigit(ch)) {
  2559.         if (isdigit(ch)) k=k*16+(inbyte()-'0');
  2560.         else k=k*16+10+(toupper(inbyte())-'A');
  2561.         }
  2562.       }
  2563.     else while (ch>='0' && ch<='7') k=k*8+(inbyte()-'0');
  2564.     }
  2565.   else while (isdigit(ch)) k=k*10+(inbyte()-'0');
  2566.   if (minus) k=(-k);
  2567.   val[0]=k;
  2568.   return 1;
  2569.   }
  2570.  
  2571. pstr(val)  int val[]; {
  2572.   int k;
  2573.   k=0;
  2574.   if (match("'")==0) return 0;
  2575.   while(ch!='\'')    k=(k&255)*256 + (litchar()&255);
  2576.   gch();
  2577.   val[0]=k;
  2578.   return 1;
  2579.   }
  2580.  
  2581. qstr(val)  int val[]; {
  2582.   char c;
  2583.   if (match(quote)==0) return 0;
  2584.   val[0]=litptr;
  2585.   while (ch!='"') {
  2586.     if(ch==0) break;
  2587.     stowlit(litchar(), 1);
  2588.     }
  2589.   gch();
  2590.   litq[litptr++]=0;
  2591.   return 1;
  2592.   }
  2593.  
  2594. stowlit(value, size) int value, size; {
  2595.   if((litptr+size) >= LITMAX) {
  2596.     error("literal queue overflow");
  2597.     abort(ERRCODE);
  2598.     }
  2599.   putint(value, litq+litptr, size);
  2600.   litptr=litptr+size;
  2601.   }
  2602.  
  2603. /*
  2604. ** return current literal char & bump lptr
  2605. */
  2606. litchar() {
  2607.   int i, oct;
  2608.   if((ch!='\\')|(nch==0)) return gch();
  2609.   gch();
  2610.   switch(ch) {
  2611.     case 'n': gch(); return NEWLINE;
  2612.     case 't': gch(); return  9;  /* HT */
  2613.     case 'b': gch(); return  8;  /* BS */
  2614.     case 'f': gch(); return 12;  /* FF */
  2615.     }
  2616.   i=3; oct=0;
  2617.   while(((i--)>0)&(ch>='0')&(ch<='7')) oct=(oct<<3)+gch()-'0';
  2618.   if(i==2) return gch(); else return oct;
  2619.   }
  2620.  
  2621. >>> CC4.C 420
  2622. /*
  2623. ** Small-C Compiler Part 4
  2624. */
  2625. #include <stdio.h>
  2626. #include "cc.def"
  2627.  
  2628. extern char
  2629.   *cptr, 
  2630. #ifdef DYNAMIC
  2631.   *macn,
  2632.   *symtab,
  2633. #else
  2634.   macn[MACNSIZE],
  2635.   symtab[SYMTBSZ],
  2636. #endif
  2637. #ifdef OPTIMIZE
  2638.  optimize,
  2639. #endif
  2640.   ssname[NAMESIZE];
  2641.  
  2642. extern int
  2643. #ifdef DYNAMIC
  2644.   *stage,
  2645. #else
  2646.   stage[STAGESIZE*2],
  2647. #endif
  2648.   litlab,  beglab,  csp, output, oldseg,
  2649.  *stagenext, *stagetail, *stagelast;
  2650.  
  2651. #include "cc41.c"
  2652. #include "cc42.c"
  2653.  
  2654. >>> CC41.C 4333
  2655. /*
  2656. ** print all assembler info before any code is generated
  2657. ** and ensure that the segments appear in the correct order.
  2658. */
  2659. header()  {
  2660.   toseg(CODESEG);
  2661.   ol("extrn __link: near");
  2662.   ol("extrn __eq: near");
  2663.   ol("extrn __ne: near");
  2664.   ol("extrn __le: near");
  2665.   ol("extrn __lt: near");
  2666.   ol("extrn __ge: near");
  2667.   ol("extrn __gt: near");
  2668.   ol("extrn __ule: near");
  2669.   ol("extrn __ult: near");
  2670.   ol("extrn __uge: near");
  2671.   ol("extrn __ugt: near");
  2672.   ol("extrn __lneg: near");
  2673.   ol("extrn __switch: near");
  2674.   ol("dw 0"); /* ensure non-zero code pointers, retain word alignment */
  2675.   toseg(DATASEG);
  2676.   ol("dw 0"); /* ensure non-zero data pointers, retain word alignment */
  2677.   }
  2678.  
  2679. /*
  2680. ** print any assembler stuff needed at the end
  2681. */
  2682. trailer()  {  
  2683. #ifndef LINK
  2684.   if((beglab == 1)|(beglab > 9000)) {
  2685.     /* implementation dependent trailer code goes here */
  2686.     }
  2687. #else
  2688.   cptr=STARTGLB;
  2689.   while(cptr<ENDGLB) {
  2690.     if(cptr[IDENT]==FUNCTION && cptr[CLASS]==AUTOEXT)
  2691.       external(cptr+NAME,0,FUNCTION);
  2692.     cptr+=SYMMAX;
  2693.     }
  2694. #endif
  2695.   toseg(NULL);
  2696.   ol("END");
  2697.   }
  2698.  
  2699. /*
  2700. ** remember where we are in the queue in case we have to back up.
  2701. */
  2702. setstage(before, start) int *before, *start; {
  2703.   if((*before=stagenext)==0) stagenext=stage;
  2704.   *start=stagenext;
  2705.   }
  2706.  
  2707. /*
  2708. ** put code into the queue.
  2709. */
  2710. gen_code(func, value) int func, value; {
  2711.   int size;
  2712.   if (func==_PUSH) csp=csp-BPW;
  2713.   else if(func==_POP) csp=csp+BPW;
  2714.   else if(func==_MODSTK) {
  2715.     size=value;
  2716.     value-=csp;
  2717.     csp=size;
  2718.     }
  2719.   if(stagenext==0) {
  2720.     out_code(func,value);
  2721.     return;
  2722.     }
  2723.   if(stagenext >= stagelast) {
  2724.     error("staging buffer overflow");
  2725.     return;
  2726.     }
  2727.   stagenext[0] = func;
  2728.   stagenext[1] = value;
  2729.   stagenext = nextq(stagenext);
  2730.   }
  2731.  
  2732. nextq(qptr) int *qptr; {
  2733.   qptr += 2;
  2734.   if(qptr >= stagelast) qptr = stage;
  2735.   return (qptr);
  2736.   }
  2737.  
  2738. /*
  2739. ** dump the contents of the queue.
  2740. ** If start=0, throw away contents.
  2741. ** If before!=0, don't dump queue yet.
  2742. */
  2743. clearstage(before, start) int *before, *start; {
  2744.   if(before) {stagenext = before; return;}
  2745.   if(start) dumpstage();
  2746.   stagenext = 0;
  2747.   }
  2748.  
  2749. /*
  2750. ** empty the queue.
  2751. */
  2752. dumpstage() {
  2753.   stagetail = stagenext;
  2754.   stagenext = stage;
  2755.   while(stagenext < stagetail) {
  2756. #ifdef OPTIMIZE
  2757.     peephole();
  2758. #endif
  2759.     out_code(stagenext[0], stagenext[1]);
  2760.     stagenext = nextq(stagenext);
  2761.     }
  2762.   }
  2763.  
  2764. /*
  2765. ** change to a new segment
  2766. ** may be called with NULL, CODESEG, or DATASEG
  2767. */
  2768. toseg(newseg) int newseg; {
  2769.   if(oldseg==newseg) return;
  2770.   if(oldseg==CODESEG)      ol("CODE ENDS");
  2771.   else if(oldseg==DATASEG) ol("DATA ENDS");
  2772.   if(newseg==CODESEG) {
  2773.     ol("CODE SEGMENT PUBLIC");
  2774.     ol("ASSUME CS:CODE, SS:DATA, DS:DATA");
  2775.     }
  2776.   else if(newseg==DATASEG)
  2777.     ol("DATA SEGMENT PUBLIC");
  2778.   oldseg = newseg;
  2779.   }
  2780.  
  2781. /*
  2782. ** load # args before function call
  2783. */
  2784. loadargc(val) int val; {
  2785.   if(search("NOCCARGC", macn, NAMESIZE+2, MACNEND, MACNBR, 0)==0) {
  2786.     gen_code(_COUNT, val);
  2787.     }
  2788.   }
  2789.  
  2790. /*
  2791. ** declare entry point
  2792. */
  2793. public(size, ident) int size, ident;{
  2794.   if (ident == FUNCTION) toseg(CODESEG);
  2795.   else toseg(DATASEG);
  2796. #ifdef LINK
  2797.   ot("PUBLIC ");
  2798.   outname(ssname);
  2799.   nl();
  2800. #endif
  2801.   outname(ssname);
  2802.   if (ident == FUNCTION) {col(); nl();}
  2803.   }
  2804.  
  2805. /*
  2806. ** declare external reference
  2807. */
  2808. external(name, size, ident) char *name; int size, ident; {
  2809. #ifdef LINK
  2810.   if (ident == FUNCTION) toseg(CODESEG);
  2811.   else toseg(DATASEG);
  2812.   ot("EXTRN ");
  2813.   outname(name);
  2814.   col();
  2815.   outsize(size, ident);
  2816.   nl();
  2817. #endif
  2818.   }
  2819.  
  2820. /*
  2821. ** swap primary and secondary registers
  2822. */
  2823. outswap() {
  2824.   ol("XCHG AX,BX");
  2825.   }
  2826.  
  2827. /*
  2828. ** output a label of specified number
  2829. */
  2830. outlabel(lab) int lab; {
  2831.   outstr("_");
  2832.   outdec(lab);
  2833.   }
  2834.  
  2835. /*
  2836. ** output a jump to the specified label
  2837. */
  2838. outjump(lab) int lab; {
  2839.   ot("JMP ");
  2840.   outlabel(lab);
  2841.   nl();
  2842.   }
  2843.  
  2844. /*
  2845. ** output the size of the object pointed to.
  2846. */
  2847. outsize(size, ident) int size, ident; {
  2848.   if ((size==1)&(ident!=POINTER)&(ident!=FUNCTION)) {outstr("BYTE");}
  2849.   else if (ident!=FUNCTION) {outstr("WORD");}
  2850.   else {outstr("NEAR");};
  2851.   }
  2852.  
  2853. /*
  2854. ** output a call
  2855. */
  2856. outcall(sname)  char *sname; {
  2857.   ot("CALL ");
  2858.   outstr(sname);
  2859.   nl();
  2860.   }
  2861.  
  2862. /*
  2863. ** test primary register against zero and jump if false
  2864. */
  2865. zerojump(oper, label, lval) int oper, label, lval[]; {
  2866.   clearstage(lval[7], 0);       /* purge conventional code */
  2867.   gen_code(oper, label);
  2868.   }
  2869.  
  2870. /*
  2871. ** point to following object(s)
  2872. */
  2873. point() {
  2874.   ol(" DW $+2");
  2875.   }
  2876.  
  2877. >>> CC42.C 9580
  2878. #ifdef OPTIMIZE
  2879. /*
  2880. ** Peephole Optimizer
  2881. */
  2882. int
  2883.   seq01[] = {_PUSH, _ANY, _POP, NULL},
  2884.   seq02[] = {_GSTK, _IMMED2, _ADD, _GINT, NULL},
  2885.   seq03[] = {_GSTK, _IMMED2, _ADD, _GCHAR, NULL},
  2886.   seq04[] = {_OFFSET, _IMMED2, _ADD, _GINT, NULL},
  2887.   seq05[] = {_OFFSET, _IMMED2, _ADD, _GCHAR, NULL},
  2888.   seq08[] = {_GSTK, _GCHAR, NULL},
  2889.   seq09[] = {_GSTK, _GINT, NULL},
  2890.   seq10[] = {_MOVE, _IMMED, _SUB, NULL},
  2891.   seq11[] = {_INC, _PINT, _DEC, NULL},
  2892.   seq12[] = {_DEC, _PINT, _INC, NULL},
  2893.   seq13[] = {_INC, _PCHAR, _DEC, NULL},
  2894.   seq14[] = {_DEC, _PCHAR, _INC, NULL},
  2895.   seq15[] = {_INC, _SINT, _DEC, NULL},
  2896.   seq16[] = {_INC, _SCHAR, _DEC, NULL},
  2897.   seq17[] = {_DEC, _SINT, _INC, NULL},
  2898.   seq18[] = {_DEC, _SCHAR, _INC, NULL},
  2899.   seq19[] = {_IMMED2, _ADD, NULL};
  2900.  
  2901. peephole() {
  2902.   while(optimize) {
  2903.     if(peep(seq01)) {          /* _PUSH_ANY_POP --> _MOVE_ANY */
  2904.       stagenext[4] = stagenext[2];
  2905.       stagenext[5] = stagenext[3];
  2906.       stagenext[2] = _MOVE;
  2907.       stagenext += 2;
  2908.       }
  2909.     else if(peep(seq02)) {     /* _GSTK_IMMED2_ADD_GINT  --> _GLIO */
  2910.       stagenext[6] = _GLIO;
  2911.       stagenext[7] = getint(stagenext[1]+OFFSET, OFFSIZE) + stagenext[3];
  2912.       stagenext += 6;
  2913.       }
  2914.     else if(peep(seq03)) {     /* _GSTK_IMMED2_ADD_GCHAR --> _GLCO */
  2915.       stagenext[6] = _GLCO;
  2916.       stagenext[7] = getint(stagenext[1]+OFFSET, OFFSIZE) + stagenext[3];
  2917.       stagenext += 6;
  2918.       }
  2919.     else if(peep(seq04)) {     /* _OFFSET_IMMED2_ADD_GINT --> _GGIO */
  2920.       stagenext[4] = _GGIO1;
  2921.       stagenext[5] = stagenext[1];
  2922.       stagenext[6] = _GGIO2;
  2923.       stagenext[7] = stagenext[3];
  2924.       stagenext += 4;
  2925.       }
  2926.     else if(peep(seq05)) {     /* _OFFSET_IMMED2_ADD_GCHAR --> _GGCO */
  2927.       stagenext[4] = _GGCO1;
  2928.       stagenext[5] = stagenext[1];
  2929.       stagenext[6] = _GGCO2;
  2930.       stagenext[7] = stagenext[3];
  2931.       stagenext += 4;
  2932.       }
  2933.     else if(peep(seq08))       /* _GSTK_GCHAR --> _FCHAR */
  2934.       merge(_FCHAR);
  2935.     else if(peep(seq09))       /* _GSTK_GINT  --> _FINT */
  2936.       merge(_FINT);
  2937.     else if(peep(seq10)) {     /* _MOVE_IMMED_SUB --> _SUBI */
  2938.       stagenext[4] = _SUBI;
  2939.       stagenext[5] = stagenext[3];
  2940.       stagenext += 4;
  2941.       }
  2942.     else if(peep(seq11)) {     /* _INC_PINT_DEC --> _INT_I */
  2943.       stagenext[4] = _INT_I;
  2944.       stagenext += 4;
  2945.       }
  2946.     else if(peep(seq12)) {     /* _DEC_PINT_INC --> _INT_D */
  2947.       stagenext[4] = _INT_D;
  2948.       stagenext += 4;
  2949.       }
  2950.     else if(peep(seq13)) {     /* _INC_PCHAR_DEC --> _CHAR_I */
  2951.       stagenext[4] = _CHAR_I;
  2952.       stagenext += 4;
  2953.       }
  2954.     else if(peep(seq14)) {     /* _DEC_PCHAR_INC --> _CHAR_D */
  2955.       stagenext[4] = _CHAR_D;
  2956.       stagenext += 4;
  2957.       }
  2958.     else if(peep(seq15) ||
  2959.             peep(seq16)) {     /* _INC_Sxxx_DEC --> _XXX_I1 */
  2960.       stagenext[2] = _XXX_I1;
  2961.       stagenext[4] = _XXX_X2;
  2962.       stagenext += 2;
  2963.       }
  2964.     else if(peep(seq17) ||
  2965.             peep(seq18)) {     /* _DEC_Sxxx_INC --> _XXX_D1 */
  2966.       stagenext[2] = _XXX_D1;
  2967.       stagenext[4] = _XXX_X2;
  2968.       stagenext += 2;
  2969.       }
  2970.     else if(peep(seq19))       /* _IMMED2_ADD --> _ADDI */ 
  2971.       merge(_ADDI);
  2972.     else break;
  2973.     }
  2974.   }
  2975.  
  2976. /*
  2977. ** peep into the staging buffer for a match
  2978. */
  2979. peep(seq) int *seq; {
  2980.   int *next;
  2981.   next = stagenext;
  2982.   while(*seq) {
  2983.     if(next >= stagetail || (*seq != _ANY && *seq != *next))
  2984.       return (NO);
  2985.     next += 2;
  2986.     ++seq;
  2987.     }
  2988.   return (YES);
  2989.   }
  2990.  
  2991. /*
  2992. ** Merge top two p-codes into one with code "func" and the top value.
  2993. */
  2994. merge(func) int func; {
  2995.   stagenext[2] = func;
  2996.   stagenext[3] = stagenext[1];
  2997.   stagenext += 2;
  2998.   }
  2999. #endif
  3000.  
  3001. /*
  3002. ** take code out of the queue.
  3003. */
  3004. out_code(func, value) int func, value; {
  3005.   char *str;
  3006.   str = value;
  3007.   switch(func) {
  3008.     case _LABEL: {outlabel(value); col(); nl(); break;}
  3009.     case _RLAB:  {outlabel(value); break;}
  3010.     case _GCHAR: {ol("MOV BX,AX"); ol("MOV AL,[BX]"); ol("CBW"); break;}
  3011.     case _GINT:  {ol("MOV BX,AX"); ol("MOV AX,[BX]"); break;}
  3012.     case _LINT:  {ot("MOV AX,"); outname(str+NAME); nl(); break;}
  3013.     case _LCHAR: {ot("MOV AL,"); outname(str+NAME); nl(); ol("CBW"); break;}
  3014.     case _GSTK:  {ot("LEA AX,"); outdec(getint(str+OFFSET, OFFSIZE));
  3015.                   outstr("[BP]"); nl(); break;}
  3016.     case _SCHAR: {ot("MOV "); outname(str+NAME); outstr(",AL"); nl(); break;}
  3017.     case _SINT:  {ot("MOV "); outname(str+NAME); outstr(",AX"); nl(); break;}
  3018.     case _PINT:  {ol("MOV [BX],AX"); break;}
  3019.     case _PCHAR: {ol("MOV [BX],AL"); break;}
  3020.     case _MOVE:  {ol("MOV BX,AX"); break;}
  3021.     case _SWAP:  {outswap(); break;}
  3022.     case _OFFSET:{ot("MOV AX,OFFSET "); outname(str+NAME); nl(); break;}
  3023.     case _STRING:{ot("MOV AX,OFFSET "); outlabel(litlab); outstr("+");
  3024.                   outdec(value); nl(); break;}
  3025.     case _IMMED: {
  3026.       if(value) {ot("MOV AX,"); outdec(value);}
  3027.       else ot("XOR AX,AX");
  3028.       nl();
  3029.       break;
  3030.       }
  3031.     case _IMMED2: {
  3032.       if(value) {ot("MOV BX,"); outdec(value);}
  3033.       else ot("XOR BX,BX");
  3034.       nl();
  3035.       break;
  3036.       }
  3037.     case _COUNT: {
  3038.       if(value) {ot("MOV CL,"); outdec(value);}
  3039.       else ot("XOR CL,CL");
  3040.       nl();
  3041.       break;
  3042.       }
  3043.     case _PUSH:    {ol("PUSH AX"); break;}
  3044.     case _POP:     {ol("POP BX"); break;}
  3045.     case _SWAPSTK: {ol("POP BX"); ol("XCHG AX,BX"); ol("PUSH BX"); break;}
  3046.     case _SW:      {outcall("__SWITCH"); break;}
  3047.     case _CALL:    {ot("CALL "); outname(str+NAME); nl(); break;}
  3048.     case _FUNC:    {ol("PUSH BP"); ol("MOV BP,SP"); break;}
  3049.     case _RET:     {ol("POP BP"); ol("RET"); break;}
  3050.     case _CALLSTK: {ol("CALL AX"); break;}
  3051.     case _JUMP:    {outjump(value); break;}
  3052.     case _TESTJUMP:{ol("OR AX,AX"); ol("JNZ $+5"); outjump(value); break;}
  3053.     case _DB:      {ot(" DB "); break;}
  3054.     case _DBZERO:  {ot(" DB "); outdec(value); outstr(" DUP(0)"); nl(); break;}
  3055.     case _DEFBYTE: {ot(" DB "); outdec(value); nl(); break;}
  3056.     case _DW:      {ot(" DW "); break;}
  3057.     case _DWZERO:  {ot(" DW "); outdec(value); outstr(" DUP(0)"); nl(); break;}
  3058.     case _DEFWORD: {ot(" DW "); outdec(value); nl(); break;}
  3059.     case _DEFLABEL:{ot(" DW "); outlabel(value); nl(); break;}
  3060.     case _MODSTK: {
  3061.       if(value) {ot("ADD SP,"); outdec(value); nl();}
  3062.       break;
  3063.       }
  3064.     case _DBL:   {ol("ADD AX,AX"); break;}
  3065.     case _DBL2:  {ol("ADD BX,BX"); break;}
  3066.     case _ADD:   {ol("ADD AX,BX"); break;}
  3067.     case _SUB:   {outswap(); ol("SUB AX,BX"); break;}
  3068.     case _MULT:  {ol("IMUL BX"); break;}
  3069.     case _DIV:   {outswap(); ol("CWD"); ol("IDIV BX"); break;}
  3070.     case _MOD:   {outswap(); ol("CWD"); ol("IDIV BX"); ol("MOV AX,DX"); break;}
  3071.     case _OR:    {ol("OR AX,BX"); break;}
  3072.     case _XOR:   {ol("XOR AX,BX"); break;}
  3073.     case _AND:   {ol("AND AX,BX"); break;}
  3074.     case _LNEG:  {outcall("__LNEG"); break;}
  3075.     case _ASR:   {ol("MOV CX,AX"); ol("MOV AX,BX"); ol("SAR AX,CL"); break;}
  3076.     case _ASL:   {ol("MOV CX,AX"); ol("MOV AX,BX"); ol("SAL AX,CL"); break;}
  3077.     case _NEG:   {ol("NEG AX"); break;}
  3078.     case _COM:   {ol("NOT AX"); break;}
  3079.     case _INC:   {while(1) {ol("INC AX"); if(--value < 1) break;} break;}
  3080.     case _DEC:   {while(1) {ol("DEC AX"); if(--value < 1) break;} break;}
  3081.     case _EQ:    {outcall("__EQ"); break;}
  3082.     case _EQ0:   {ol("OR AX,AX"); ol("JZ $+5"); outjump(value); break;}
  3083.     case _NE:    {outcall("__NE"); break;}
  3084.     case _NE0:   {ol("OR AX,AX"); ol("JNZ $+5"); outjump(value); break;}
  3085.     case _LT:    {outcall("__LT"); break;}
  3086.     case _LT0:   {ol("OR AX,AX"); ol("JL $+5"); outjump(value); break;}
  3087.     case _LE:    {outcall("__LE"); break;}
  3088.     case _LE0:   {ol("OR AX,AX"); ol("JLE $+5"); outjump(value); break;}
  3089.     case _GT:    {outcall("__GT"); break;}
  3090.     case _GT0:   {ol("OR AX,AX"); ol("JG $+5"); outjump(value); break;}
  3091.     case _GE:    {outcall("__GE"); break;}
  3092.     case _GE0:   {ol("OR AX,AX"); ol("JGE $+5"); outjump(value); break;}
  3093.     case _ULT:   {outcall("__ULT"); break;}
  3094.     case _ULT0:  {outjump(value); break;}
  3095.     case _ULE:   {outcall("__ULE"); break;}
  3096.     case _UGT:   {outcall("__UGT"); break;}
  3097.     case _UGE:   {outcall("__UGE"); break;}
  3098.     case _GLIO:  {
  3099.       ot("LEA BX,"); outdec(value); outstr("[BP]"); nl();
  3100.       ol("MOV AX,[BX]");
  3101.       break;
  3102.       }
  3103.     case _GLCO:  {
  3104.       ot("LEA BX,"); outdec(value); outstr("[BP]"); nl();
  3105.       ol("MOV AL,[BX]");
  3106.       ol("CBW");
  3107.       break;
  3108.       }
  3109.     case _GGIO1: {ot("MOV BX,OFFSET "); outname(str+NAME); break;}
  3110.     case _GGIO2: {
  3111.       if(value >= 0) outstr("+"); outdec(value); nl();
  3112.       ol("MOV AX,[BX]");
  3113.       break;
  3114.       }
  3115.     case _GGCO1: {ot("MOV BX,OFFSET "); outname(str+NAME); break;}
  3116.     case _GGCO2: {
  3117.       if(value >= 0) outstr("+"); outdec(value); nl();
  3118.       ol("MOV AL,[BX]");
  3119.       ol("CBW");
  3120.       break;
  3121.       }
  3122.     case _INT_I: {ot("ADD WORD PTR [BX],"); outdec(value); nl(); break;}
  3123.     case _INT_D: {ot("SUB WORD PTR [BX],"); outdec(value); nl(); break;}
  3124.     case _CHAR_I:{ot("ADD BYTE PTR [BX],"); outdec(value); nl(); break;}
  3125.     case _CHAR_D:{ot("SUB BYTE PTR [BX],"); outdec(value); nl(); break;}
  3126.     case _XXX_I1:{ot("ADD "); outname(str+NAME); break;}
  3127.     case _XXX_D1:{ot("SUB "); outname(str+NAME); break;}
  3128.     case _XXX_X2:{outstr(","); outdec(value); nl(); break;}
  3129.     case _FINT: {
  3130.       ot("LEA BX,"); outdec(getint(str+OFFSET, OFFSIZE)); outstr("[BP]"); nl();
  3131.       ol("MOV AX,[BX]");
  3132.       break;
  3133.       }
  3134.     case _FCHAR: {
  3135.       ot("LEA BX,"); outdec(getint(str+OFFSET, OFFSIZE)); outstr("[BP]"); nl();
  3136.       ol("MOV AL,[BX]");
  3137.       ol("CBW");
  3138.       break;
  3139.       }
  3140.     case _ADDI: {ot("ADD AX,"); outdec(value); nl(); break;}
  3141.     case _SUBI: {ot("SUB AX,"); outdec(value); nl(); break;}
  3142.  
  3143.     default:     {error("bad pcode"); break;}
  3144.     }
  3145.   }
  3146.  
  3147.